mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-05-24 05:29:12 +00:00
Added SDL_SetRenderTextureAddressMode() and SDL_GetRenderTextureAddressMode()
Fixes https://github.com/libsdl-org/SDL/issues/4820 Fixes https://github.com/libsdl-org/SDL/issues/12610
This commit is contained in:
parent
eb918af3dc
commit
633b9f6fb1
20 changed files with 623 additions and 531 deletions
|
@ -98,6 +98,21 @@ typedef enum SDL_TextureAccess
|
||||||
SDL_TEXTUREACCESS_TARGET /**< Texture can be used as a render target */
|
SDL_TEXTUREACCESS_TARGET /**< Texture can be used as a render target */
|
||||||
} SDL_TextureAccess;
|
} SDL_TextureAccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The addressing mode for a texture when used in SDL_RenderGeometry().
|
||||||
|
*
|
||||||
|
* This affects how texture coordinates are interpreted outside of [0, 1]
|
||||||
|
*
|
||||||
|
* \since This enum is available since SDL 3.4.0.
|
||||||
|
*/
|
||||||
|
typedef enum SDL_TextureAddressMode
|
||||||
|
{
|
||||||
|
SDL_TEXTURE_ADDRESS_INVALID = -1,
|
||||||
|
SDL_TEXTURE_ADDRESS_AUTO, /**< Wrapping is enabled if texture coordinates are outside [0, 1], this is the default */
|
||||||
|
SDL_TEXTURE_ADDRESS_CLAMP, /**< Texture coordinates are clamped to the [0, 1] range */
|
||||||
|
SDL_TEXTURE_ADDRESS_WRAP, /**< The texture is repeated (tiled) */
|
||||||
|
} SDL_TextureAddressMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How the logical size is mapped to the output.
|
* How the logical size is mapped to the output.
|
||||||
*
|
*
|
||||||
|
@ -2294,6 +2309,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RenderTexture9GridTiled(SDL_Renderer *rende
|
||||||
* \since This function is available since SDL 3.2.0.
|
* \since This function is available since SDL 3.2.0.
|
||||||
*
|
*
|
||||||
* \sa SDL_RenderGeometryRaw
|
* \sa SDL_RenderGeometryRaw
|
||||||
|
* \sa SDL_SetRenderTextureAddressMode
|
||||||
*/
|
*/
|
||||||
extern SDL_DECLSPEC bool SDLCALL SDL_RenderGeometry(SDL_Renderer *renderer,
|
extern SDL_DECLSPEC bool SDLCALL SDL_RenderGeometry(SDL_Renderer *renderer,
|
||||||
SDL_Texture *texture,
|
SDL_Texture *texture,
|
||||||
|
@ -2326,6 +2342,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RenderGeometry(SDL_Renderer *renderer,
|
||||||
* \since This function is available since SDL 3.2.0.
|
* \since This function is available since SDL 3.2.0.
|
||||||
*
|
*
|
||||||
* \sa SDL_RenderGeometry
|
* \sa SDL_RenderGeometry
|
||||||
|
* \sa SDL_SetRenderTextureAddressMode
|
||||||
*/
|
*/
|
||||||
extern SDL_DECLSPEC bool SDLCALL SDL_RenderGeometryRaw(SDL_Renderer *renderer,
|
extern SDL_DECLSPEC bool SDLCALL SDL_RenderGeometryRaw(SDL_Renderer *renderer,
|
||||||
SDL_Texture *texture,
|
SDL_Texture *texture,
|
||||||
|
@ -2335,6 +2352,38 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RenderGeometryRaw(SDL_Renderer *renderer,
|
||||||
int num_vertices,
|
int num_vertices,
|
||||||
const void *indices, int num_indices, int size_indices);
|
const void *indices, int num_indices, int size_indices);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the texture addressing mode used in SDL_RenderGeometry().
|
||||||
|
*
|
||||||
|
* \param renderer the rendering context.
|
||||||
|
* \param u_mode the SDL_TextureAddressMode to use for horizontal texture coordinates in SDL_RenderGeometry().
|
||||||
|
* \param v_mode the SDL_TextureAddressMode to use for vertical texture coordinates in SDL_RenderGeometry().
|
||||||
|
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.4.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_RenderGeometry
|
||||||
|
* \sa SDL_RenderGeometryRaw
|
||||||
|
* \sa SDL_GetRenderTextureAddressMode
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_SetRenderTextureAddressMode(SDL_Renderer *renderer, SDL_TextureAddressMode u_mode, SDL_TextureAddressMode v_mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the texture addressing mode used in SDL_RenderGeometry().
|
||||||
|
*
|
||||||
|
* \param renderer the rendering context.
|
||||||
|
* \param u_mode a pointer filled in with the SDL_TextureAddressMode to use for horizontal texture coordinates in SDL_RenderGeometry(), may be NULL.
|
||||||
|
* \param v_mode a pointer filled in with the SDL_TextureAddressMode to use for vertical texture coordinates in SDL_RenderGeometry(), may be NULL.
|
||||||
|
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.4.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_SetRenderTextureAddressMode
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_GetRenderTextureAddressMode(SDL_Renderer *renderer, SDL_TextureAddressMode *u_mode, SDL_TextureAddressMode *v_mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read pixels from the current rendering target.
|
* Read pixels from the current rendering target.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1246,6 +1246,8 @@ SDL3_0.0.0 {
|
||||||
SDL_SetWindowProgressValue;
|
SDL_SetWindowProgressValue;
|
||||||
SDL_GetWindowProgressState;
|
SDL_GetWindowProgressState;
|
||||||
SDL_GetWindowProgressValue;
|
SDL_GetWindowProgressValue;
|
||||||
|
SDL_SetRenderTextureAddressMode;
|
||||||
|
SDL_GetRenderTextureAddressMode;
|
||||||
# extra symbols go here (don't modify this line)
|
# extra symbols go here (don't modify this line)
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1271,3 +1271,5 @@
|
||||||
#define SDL_SetWindowProgressValue SDL_SetWindowProgressValue_REAL
|
#define SDL_SetWindowProgressValue SDL_SetWindowProgressValue_REAL
|
||||||
#define SDL_GetWindowProgressState SDL_GetWindowProgressState_REAL
|
#define SDL_GetWindowProgressState SDL_GetWindowProgressState_REAL
|
||||||
#define SDL_GetWindowProgressValue SDL_GetWindowProgressValue_REAL
|
#define SDL_GetWindowProgressValue SDL_GetWindowProgressValue_REAL
|
||||||
|
#define SDL_SetRenderTextureAddressMode SDL_SetRenderTextureAddressMode_REAL
|
||||||
|
#define SDL_GetRenderTextureAddressMode SDL_GetRenderTextureAddressMode_REAL
|
||||||
|
|
|
@ -1279,3 +1279,5 @@ SDL_DYNAPI_PROC(bool,SDL_SetWindowProgressState,(SDL_Window *a,SDL_ProgressState
|
||||||
SDL_DYNAPI_PROC(bool,SDL_SetWindowProgressValue,(SDL_Window *a,float b),(a,b),return)
|
SDL_DYNAPI_PROC(bool,SDL_SetWindowProgressValue,(SDL_Window *a,float b),(a,b),return)
|
||||||
SDL_DYNAPI_PROC(SDL_ProgressState,SDL_GetWindowProgressState,(SDL_Window *a),(a),return)
|
SDL_DYNAPI_PROC(SDL_ProgressState,SDL_GetWindowProgressState,(SDL_Window *a),(a),return)
|
||||||
SDL_DYNAPI_PROC(float,SDL_GetWindowProgressValue,(SDL_Window *a),(a),return)
|
SDL_DYNAPI_PROC(float,SDL_GetWindowProgressValue,(SDL_Window *a),(a),return)
|
||||||
|
SDL_DYNAPI_PROC(bool,SDL_SetRenderTextureAddressMode,(SDL_Renderer *a,SDL_TextureAddressMode b,SDL_TextureAddressMode c),(a,b,c),return)
|
||||||
|
SDL_DYNAPI_PROC(bool,SDL_GetRenderTextureAddressMode,(SDL_Renderer *a,SDL_TextureAddressMode *b,SDL_TextureAddressMode *c),(a,b,c),return)
|
||||||
|
|
|
@ -584,7 +584,8 @@ static SDL_RenderCommand *PrepQueueCmdDraw(SDL_Renderer *renderer, const SDL_Ren
|
||||||
if (texture) {
|
if (texture) {
|
||||||
cmd->data.draw.texture_scale_mode = texture->scaleMode;
|
cmd->data.draw.texture_scale_mode = texture->scaleMode;
|
||||||
}
|
}
|
||||||
cmd->data.draw.texture_address_mode = SDL_TEXTURE_ADDRESS_CLAMP;
|
cmd->data.draw.texture_address_mode_u = SDL_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
cmd->data.draw.texture_address_mode_v = SDL_TEXTURE_ADDRESS_CLAMP;
|
||||||
cmd->data.draw.gpu_render_state = renderer->gpu_render_state;
|
cmd->data.draw.gpu_render_state = renderer->gpu_render_state;
|
||||||
if (renderer->gpu_render_state) {
|
if (renderer->gpu_render_state) {
|
||||||
renderer->gpu_render_state->last_command_generation = renderer->render_command_generation;
|
renderer->gpu_render_state->last_command_generation = renderer->render_command_generation;
|
||||||
|
@ -727,13 +728,15 @@ static bool QueueCmdGeometry(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||||
const float *uv, int uv_stride,
|
const float *uv, int uv_stride,
|
||||||
int num_vertices,
|
int num_vertices,
|
||||||
const void *indices, int num_indices, int size_indices,
|
const void *indices, int num_indices, int size_indices,
|
||||||
float scale_x, float scale_y, SDL_TextureAddressMode texture_address_mode)
|
float scale_x, float scale_y,
|
||||||
|
SDL_TextureAddressMode texture_address_mode_u, SDL_TextureAddressMode texture_address_mode_v)
|
||||||
{
|
{
|
||||||
SDL_RenderCommand *cmd;
|
SDL_RenderCommand *cmd;
|
||||||
bool result = false;
|
bool result = false;
|
||||||
cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_GEOMETRY, texture);
|
cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_GEOMETRY, texture);
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
cmd->data.draw.texture_address_mode = texture_address_mode;
|
cmd->data.draw.texture_address_mode_u = texture_address_mode_u;
|
||||||
|
cmd->data.draw.texture_address_mode_v = texture_address_mode_v;
|
||||||
result = renderer->QueueGeometry(renderer, cmd, texture,
|
result = renderer->QueueGeometry(renderer, cmd, texture,
|
||||||
xy, xy_stride,
|
xy, xy_stride,
|
||||||
color, color_stride, uv, uv_stride,
|
color, color_stride, uv, uv_stride,
|
||||||
|
@ -3739,7 +3742,7 @@ bool SDL_RenderLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count
|
||||||
result = QueueCmdGeometry(renderer, NULL,
|
result = QueueCmdGeometry(renderer, NULL,
|
||||||
xy, xy_stride, &renderer->color, 0 /* color_stride */, NULL, 0,
|
xy, xy_stride, &renderer->color, 0 /* color_stride */, NULL, 0,
|
||||||
num_vertices, indices, num_indices, size_indices,
|
num_vertices, indices, num_indices, size_indices,
|
||||||
1.0f, 1.0f, SDL_TEXTURE_ADDRESS_CLAMP);
|
1.0f, 1.0f, SDL_TEXTURE_ADDRESS_CLAMP, SDL_TEXTURE_ADDRESS_CLAMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_small_free(xy, isstack1);
|
SDL_small_free(xy, isstack1);
|
||||||
|
@ -3920,7 +3923,7 @@ static bool SDL_RenderTextureInternal(SDL_Renderer *renderer, SDL_Texture *textu
|
||||||
result = QueueCmdGeometry(renderer, texture,
|
result = QueueCmdGeometry(renderer, texture,
|
||||||
xy, xy_stride, &texture->color, 0 /* color_stride */, uv, uv_stride,
|
xy, xy_stride, &texture->color, 0 /* color_stride */, uv, uv_stride,
|
||||||
num_vertices, indices, num_indices, size_indices,
|
num_vertices, indices, num_indices, size_indices,
|
||||||
scale_x, scale_y, SDL_TEXTURE_ADDRESS_CLAMP);
|
scale_x, scale_y, SDL_TEXTURE_ADDRESS_CLAMP, SDL_TEXTURE_ADDRESS_CLAMP);
|
||||||
} else {
|
} else {
|
||||||
const SDL_FRect rect = { dstrect->x * scale_x, dstrect->y * scale_y, dstrect->w * scale_x, dstrect->h * scale_y };
|
const SDL_FRect rect = { dstrect->x * scale_x, dstrect->y * scale_y, dstrect->w * scale_x, dstrect->h * scale_y };
|
||||||
result = QueueCmdCopy(renderer, texture, srcrect, &rect);
|
result = QueueCmdCopy(renderer, texture, srcrect, &rect);
|
||||||
|
@ -4083,7 +4086,7 @@ bool SDL_RenderTextureAffine(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||||
&texture->color, 0 /* color_stride */,
|
&texture->color, 0 /* color_stride */,
|
||||||
uv, uv_stride,
|
uv, uv_stride,
|
||||||
num_vertices, indices, num_indices, size_indices,
|
num_vertices, indices, num_indices, size_indices,
|
||||||
scale_x, scale_y, SDL_TEXTURE_ADDRESS_CLAMP
|
scale_x, scale_y, SDL_TEXTURE_ADDRESS_CLAMP, SDL_TEXTURE_ADDRESS_CLAMP
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -4233,7 +4236,7 @@ bool SDL_RenderTextureRotated(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||||
result = QueueCmdGeometry(renderer, texture,
|
result = QueueCmdGeometry(renderer, texture,
|
||||||
xy, xy_stride, &texture->color, 0 /* color_stride */, uv, uv_stride,
|
xy, xy_stride, &texture->color, 0 /* color_stride */, uv, uv_stride,
|
||||||
num_vertices, indices, num_indices, size_indices,
|
num_vertices, indices, num_indices, size_indices,
|
||||||
scale_x, scale_y, SDL_TEXTURE_ADDRESS_CLAMP);
|
scale_x, scale_y, SDL_TEXTURE_ADDRESS_CLAMP, SDL_TEXTURE_ADDRESS_CLAMP);
|
||||||
} else {
|
} else {
|
||||||
result = QueueCmdCopyEx(renderer, texture, &real_srcrect, dstrect, angle, &real_center, flip, scale_x, scale_y);
|
result = QueueCmdCopyEx(renderer, texture, &real_srcrect, dstrect, angle, &real_center, flip, scale_x, scale_y);
|
||||||
}
|
}
|
||||||
|
@ -4285,7 +4288,8 @@ static bool SDL_RenderTextureTiled_Wrap(SDL_Renderer *renderer, SDL_Texture *tex
|
||||||
return QueueCmdGeometry(renderer, texture,
|
return QueueCmdGeometry(renderer, texture,
|
||||||
xy, xy_stride, &texture->color, 0 /* color_stride */, uv, uv_stride,
|
xy, xy_stride, &texture->color, 0 /* color_stride */, uv, uv_stride,
|
||||||
num_vertices, indices, num_indices, size_indices,
|
num_vertices, indices, num_indices, size_indices,
|
||||||
view->current_scale.x, view->current_scale.y, SDL_TEXTURE_ADDRESS_WRAP);
|
view->current_scale.x, view->current_scale.y,
|
||||||
|
SDL_TEXTURE_ADDRESS_WRAP, SDL_TEXTURE_ADDRESS_WRAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool SDL_RenderTextureTiled_Iterate(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FRect *srcrect, float scale, const SDL_FRect *dstrect)
|
static bool SDL_RenderTextureTiled_Iterate(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FRect *srcrect, float scale, const SDL_FRect *dstrect)
|
||||||
|
@ -5032,7 +5036,7 @@ static bool SDLCALL SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer,
|
||||||
result = QueueCmdGeometry(renderer, texture,
|
result = QueueCmdGeometry(renderer, texture,
|
||||||
xy, xy_stride, color, color_stride, uv, uv_stride,
|
xy, xy_stride, color, color_stride, uv, uv_stride,
|
||||||
num_vertices, prev, 3, 4,
|
num_vertices, prev, 3, 4,
|
||||||
scale_x, scale_y, SDL_TEXTURE_ADDRESS_CLAMP);
|
scale_x, scale_y, SDL_TEXTURE_ADDRESS_CLAMP, SDL_TEXTURE_ADDRESS_CLAMP);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -5052,7 +5056,7 @@ static bool SDLCALL SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer,
|
||||||
result = QueueCmdGeometry(renderer, texture,
|
result = QueueCmdGeometry(renderer, texture,
|
||||||
xy, xy_stride, color, color_stride, uv, uv_stride,
|
xy, xy_stride, color, color_stride, uv, uv_stride,
|
||||||
num_vertices, prev, 3, 4,
|
num_vertices, prev, 3, 4,
|
||||||
scale_x, scale_y, SDL_TEXTURE_ADDRESS_CLAMP);
|
scale_x, scale_y, SDL_TEXTURE_ADDRESS_CLAMP, SDL_TEXTURE_ADDRESS_CLAMP);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -5077,7 +5081,8 @@ bool SDL_RenderGeometryRaw(SDL_Renderer *renderer,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int count = indices ? num_indices : num_vertices;
|
int count = indices ? num_indices : num_vertices;
|
||||||
SDL_TextureAddressMode texture_address_mode;
|
SDL_TextureAddressMode texture_address_mode_u;
|
||||||
|
SDL_TextureAddressMode texture_address_mode_v;
|
||||||
|
|
||||||
CHECK_RENDERER_MAGIC(renderer, false);
|
CHECK_RENDERER_MAGIC(renderer, false);
|
||||||
|
|
||||||
|
@ -5132,17 +5137,37 @@ bool SDL_RenderGeometryRaw(SDL_Renderer *renderer,
|
||||||
texture = texture->native;
|
texture = texture->native;
|
||||||
}
|
}
|
||||||
|
|
||||||
texture_address_mode = renderer->texture_address_mode;
|
texture_address_mode_u = renderer->texture_address_mode_u;
|
||||||
if (texture_address_mode == SDL_TEXTURE_ADDRESS_AUTO && texture) {
|
texture_address_mode_v = renderer->texture_address_mode_v;
|
||||||
texture_address_mode = SDL_TEXTURE_ADDRESS_CLAMP;
|
if (texture &&
|
||||||
|
(texture_address_mode_u == SDL_TEXTURE_ADDRESS_AUTO ||
|
||||||
|
texture_address_mode_u == SDL_TEXTURE_ADDRESS_AUTO)) {
|
||||||
for (i = 0; i < num_vertices; ++i) {
|
for (i = 0; i < num_vertices; ++i) {
|
||||||
const float *uv_ = (const float *)((const char *)uv + i * uv_stride);
|
const float *uv_ = (const float *)((const char *)uv + i * uv_stride);
|
||||||
float u = uv_[0];
|
float u = uv_[0];
|
||||||
float v = uv_[1];
|
float v = uv_[1];
|
||||||
if (u < 0.0f || v < 0.0f || u > 1.0f || v > 1.0f) {
|
if (u < 0.0f || u > 1.0f) {
|
||||||
texture_address_mode = SDL_TEXTURE_ADDRESS_WRAP;
|
if (texture_address_mode_u == SDL_TEXTURE_ADDRESS_AUTO) {
|
||||||
break;
|
texture_address_mode_u = SDL_TEXTURE_ADDRESS_WRAP;
|
||||||
|
if (texture_address_mode_v != SDL_TEXTURE_ADDRESS_AUTO) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (v < 0.0f || v > 1.0f) {
|
||||||
|
if (texture_address_mode_v == SDL_TEXTURE_ADDRESS_AUTO) {
|
||||||
|
texture_address_mode_v = SDL_TEXTURE_ADDRESS_WRAP;
|
||||||
|
if (texture_address_mode_u != SDL_TEXTURE_ADDRESS_AUTO) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (texture_address_mode_u == SDL_TEXTURE_ADDRESS_AUTO) {
|
||||||
|
texture_address_mode_u = SDL_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
}
|
||||||
|
if (texture_address_mode_v == SDL_TEXTURE_ADDRESS_AUTO) {
|
||||||
|
texture_address_mode_v = SDL_TEXTURE_ADDRESS_CLAMP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5168,7 +5193,9 @@ bool SDL_RenderGeometryRaw(SDL_Renderer *renderer,
|
||||||
|
|
||||||
// For the software renderer, try to reinterpret triangles as SDL_Rect
|
// For the software renderer, try to reinterpret triangles as SDL_Rect
|
||||||
#ifdef SDL_VIDEO_RENDER_SW
|
#ifdef SDL_VIDEO_RENDER_SW
|
||||||
if (renderer->software && texture_address_mode == SDL_TEXTURE_ADDRESS_CLAMP) {
|
if (renderer->software &&
|
||||||
|
texture_address_mode_u == SDL_TEXTURE_ADDRESS_CLAMP &&
|
||||||
|
texture_address_mode_v == SDL_TEXTURE_ADDRESS_CLAMP) {
|
||||||
return SDL_SW_RenderGeometryRaw(renderer, texture,
|
return SDL_SW_RenderGeometryRaw(renderer, texture,
|
||||||
xy, xy_stride, color, color_stride, uv, uv_stride, num_vertices,
|
xy, xy_stride, color, color_stride, uv, uv_stride, num_vertices,
|
||||||
indices, num_indices, size_indices);
|
indices, num_indices, size_indices);
|
||||||
|
@ -5180,7 +5207,36 @@ bool SDL_RenderGeometryRaw(SDL_Renderer *renderer,
|
||||||
xy, xy_stride, color, color_stride, uv, uv_stride,
|
xy, xy_stride, color, color_stride, uv, uv_stride,
|
||||||
num_vertices, indices, num_indices, size_indices,
|
num_vertices, indices, num_indices, size_indices,
|
||||||
view->current_scale.x, view->current_scale.y,
|
view->current_scale.x, view->current_scale.y,
|
||||||
texture_address_mode);
|
texture_address_mode_u, texture_address_mode_v);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SDL_SetRenderTextureAddressMode(SDL_Renderer *renderer, SDL_TextureAddressMode u_mode, SDL_TextureAddressMode v_mode)
|
||||||
|
{
|
||||||
|
CHECK_RENDERER_MAGIC(renderer, false);
|
||||||
|
|
||||||
|
renderer->texture_address_mode_u = u_mode;
|
||||||
|
renderer->texture_address_mode_v = v_mode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SDL_GetRenderTextureAddressMode(SDL_Renderer *renderer, SDL_TextureAddressMode *u_mode, SDL_TextureAddressMode *v_mode)
|
||||||
|
{
|
||||||
|
if (u_mode) {
|
||||||
|
*u_mode = SDL_TEXTURE_ADDRESS_INVALID;
|
||||||
|
}
|
||||||
|
if (v_mode) {
|
||||||
|
*v_mode = SDL_TEXTURE_ADDRESS_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_RENDERER_MAGIC(renderer, false);
|
||||||
|
|
||||||
|
if (u_mode) {
|
||||||
|
*u_mode = renderer->texture_address_mode_u;
|
||||||
|
}
|
||||||
|
if (v_mode) {
|
||||||
|
*v_mode = renderer->texture_address_mode_v;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Surface *SDL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
|
SDL_Surface *SDL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
|
||||||
|
|
|
@ -32,14 +32,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum SDL_TextureAddressMode
|
|
||||||
{
|
|
||||||
SDL_TEXTURE_ADDRESS_INVALID = -1,
|
|
||||||
SDL_TEXTURE_ADDRESS_AUTO,
|
|
||||||
SDL_TEXTURE_ADDRESS_CLAMP,
|
|
||||||
SDL_TEXTURE_ADDRESS_WRAP,
|
|
||||||
} SDL_TextureAddressMode;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A rectangle, with the origin at the upper left (double precision).
|
* A rectangle, with the origin at the upper left (double precision).
|
||||||
*/
|
*/
|
||||||
|
@ -187,7 +179,8 @@ typedef struct SDL_RenderCommand
|
||||||
SDL_BlendMode blend;
|
SDL_BlendMode blend;
|
||||||
SDL_Texture *texture;
|
SDL_Texture *texture;
|
||||||
SDL_ScaleMode texture_scale_mode;
|
SDL_ScaleMode texture_scale_mode;
|
||||||
SDL_TextureAddressMode texture_address_mode;
|
SDL_TextureAddressMode texture_address_mode_u;
|
||||||
|
SDL_TextureAddressMode texture_address_mode_v;
|
||||||
SDL_GPURenderState *gpu_render_state;
|
SDL_GPURenderState *gpu_render_state;
|
||||||
} draw;
|
} draw;
|
||||||
struct
|
struct
|
||||||
|
@ -312,7 +305,8 @@ struct SDL_Renderer
|
||||||
float color_scale;
|
float color_scale;
|
||||||
SDL_FColor color; /**< Color for drawing operations values */
|
SDL_FColor color; /**< Color for drawing operations values */
|
||||||
SDL_BlendMode blendMode; /**< The drawing blend mode */
|
SDL_BlendMode blendMode; /**< The drawing blend mode */
|
||||||
SDL_TextureAddressMode texture_address_mode;
|
SDL_TextureAddressMode texture_address_mode_u;
|
||||||
|
SDL_TextureAddressMode texture_address_mode_v;
|
||||||
SDL_GPURenderState *gpu_render_state;
|
SDL_GPURenderState *gpu_render_state;
|
||||||
|
|
||||||
SDL_RenderCommand *render_commands;
|
SDL_RenderCommand *render_commands;
|
||||||
|
@ -373,6 +367,12 @@ extern SDL_RenderDriver GPU_RenderDriver;
|
||||||
// Clean up any renderers at shutdown
|
// Clean up any renderers at shutdown
|
||||||
extern void SDL_QuitRender(void);
|
extern void SDL_QuitRender(void);
|
||||||
|
|
||||||
|
#define RENDER_SAMPLER_HASHKEY(scale_mode, address_u, address_v) \
|
||||||
|
(((scale_mode == SDL_SCALEMODE_NEAREST) << 0) | \
|
||||||
|
((address_u == SDL_TEXTURE_ADDRESS_WRAP) << 1) | \
|
||||||
|
((address_v == SDL_TEXTURE_ADDRESS_WRAP) << 2))
|
||||||
|
#define RENDER_SAMPLER_COUNT (((1 << 0) | (1 << 1) | (1 << 2)) + 1)
|
||||||
|
|
||||||
// Add a supported texture format to a renderer
|
// Add a supported texture format to a renderer
|
||||||
extern bool SDL_AddSupportedTextureFormat(SDL_Renderer *renderer, SDL_PixelFormat format);
|
extern bool SDL_AddSupportedTextureFormat(SDL_Renderer *renderer, SDL_PixelFormat format);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,8 @@ typedef struct
|
||||||
bool beginScene;
|
bool beginScene;
|
||||||
bool enableSeparateAlphaBlend;
|
bool enableSeparateAlphaBlend;
|
||||||
SDL_ScaleMode scaleMode[3];
|
SDL_ScaleMode scaleMode[3];
|
||||||
SDL_TextureAddressMode addressMode[3];
|
SDL_TextureAddressMode addressModeU[3];
|
||||||
|
SDL_TextureAddressMode addressModeV[3];
|
||||||
IDirect3DSurface9 *defaultRenderTarget;
|
IDirect3DSurface9 *defaultRenderTarget;
|
||||||
IDirect3DSurface9 *currentRenderTarget;
|
IDirect3DSurface9 *currentRenderTarget;
|
||||||
void *d3dxDLL;
|
void *d3dxDLL;
|
||||||
|
@ -278,8 +279,11 @@ static void D3D_InitRenderState(D3D_RenderData *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset our current address mode
|
// Reset our current address mode
|
||||||
for (int i = 0; i < SDL_arraysize(data->addressMode); ++i) {
|
for (int i = 0; i < SDL_arraysize(data->addressModeU); ++i) {
|
||||||
data->addressMode[i] = SDL_TEXTURE_ADDRESS_INVALID;
|
data->addressModeU[i] = SDL_TEXTURE_ADDRESS_INVALID;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < SDL_arraysize(data->addressModeV); ++i) {
|
||||||
|
data->addressModeV[i] = SDL_TEXTURE_ADDRESS_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the render with beginScene
|
// Start the render with beginScene
|
||||||
|
@ -937,22 +941,28 @@ static void UpdateTextureScaleMode(D3D_RenderData *data, SDL_ScaleMode scaleMode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateTextureAddressMode(D3D_RenderData *data, SDL_TextureAddressMode addressMode, unsigned index)
|
static DWORD TranslateAddressMode(SDL_TextureAddressMode addressMode)
|
||||||
{
|
{
|
||||||
if (addressMode != data->addressMode[index]) {
|
switch (addressMode) {
|
||||||
switch (addressMode) {
|
case SDL_TEXTURE_ADDRESS_CLAMP:
|
||||||
case SDL_TEXTURE_ADDRESS_CLAMP:
|
return D3DTADDRESS_CLAMP;
|
||||||
IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
case SDL_TEXTURE_ADDRESS_WRAP:
|
||||||
IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
return D3DTADDRESS_WRAP;
|
||||||
break;
|
default:
|
||||||
case SDL_TEXTURE_ADDRESS_WRAP:
|
SDL_assert(!"Unknown texture address mode");
|
||||||
IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
|
return D3DTADDRESS_CLAMP;
|
||||||
IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
|
}
|
||||||
break;
|
}
|
||||||
default:
|
|
||||||
break;
|
static void UpdateTextureAddressMode(D3D_RenderData *data, SDL_TextureAddressMode addressModeU, SDL_TextureAddressMode addressModeV, unsigned index)
|
||||||
}
|
{
|
||||||
data->addressMode[index] = addressMode;
|
if (addressModeU != data->addressModeU[index]) {
|
||||||
|
IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSU, TranslateAddressMode(addressModeU));
|
||||||
|
data->addressModeU[index] = addressModeU;
|
||||||
|
}
|
||||||
|
if (addressModeV != data->addressModeV[index]) {
|
||||||
|
IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSV, TranslateAddressMode(addressModeV));
|
||||||
|
data->addressModeV[index] = addressModeV;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1047,15 +1057,15 @@ static bool SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
|
||||||
|
|
||||||
if (texture) {
|
if (texture) {
|
||||||
UpdateTextureScaleMode(data, cmd->data.draw.texture_scale_mode, 0);
|
UpdateTextureScaleMode(data, cmd->data.draw.texture_scale_mode, 0);
|
||||||
UpdateTextureAddressMode(data, cmd->data.draw.texture_address_mode, 0);
|
UpdateTextureAddressMode(data, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v, 0);
|
||||||
|
|
||||||
#ifdef SDL_HAVE_YUV
|
#ifdef SDL_HAVE_YUV
|
||||||
D3D_TextureData *texturedata = (D3D_TextureData *)texture->internal;
|
D3D_TextureData *texturedata = (D3D_TextureData *)texture->internal;
|
||||||
if (texturedata && texturedata->yuv) {
|
if (texturedata && texturedata->yuv) {
|
||||||
UpdateTextureScaleMode(data, cmd->data.draw.texture_scale_mode, 1);
|
UpdateTextureScaleMode(data, cmd->data.draw.texture_scale_mode, 1);
|
||||||
UpdateTextureScaleMode(data, cmd->data.draw.texture_scale_mode, 2);
|
UpdateTextureScaleMode(data, cmd->data.draw.texture_scale_mode, 2);
|
||||||
UpdateTextureAddressMode(data, cmd->data.draw.texture_address_mode, 1);
|
UpdateTextureAddressMode(data, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v, 1);
|
||||||
UpdateTextureAddressMode(data, cmd->data.draw.texture_address_mode, 2);
|
UpdateTextureAddressMode(data, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v, 2);
|
||||||
}
|
}
|
||||||
#endif // SDL_HAVE_YUV
|
#endif // SDL_HAVE_YUV
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,16 +50,6 @@
|
||||||
/* !!! FIXME: vertex buffer bandwidth could be lower; only use UV coords when
|
/* !!! FIXME: vertex buffer bandwidth could be lower; only use UV coords when
|
||||||
!!! FIXME: textures are needed. */
|
!!! FIXME: textures are needed. */
|
||||||
|
|
||||||
// Sampler types
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
D3D11_SAMPLER_NEAREST_CLAMP,
|
|
||||||
D3D11_SAMPLER_NEAREST_WRAP,
|
|
||||||
D3D11_SAMPLER_LINEAR_CLAMP,
|
|
||||||
D3D11_SAMPLER_LINEAR_WRAP,
|
|
||||||
D3D11_SAMPLER_COUNT
|
|
||||||
} D3D11_Sampler;
|
|
||||||
|
|
||||||
// Vertex shader, common values
|
// Vertex shader, common values
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -178,7 +168,7 @@ typedef struct
|
||||||
ID3D11PixelShader *pixelShaders[NUM_SHADERS];
|
ID3D11PixelShader *pixelShaders[NUM_SHADERS];
|
||||||
int blendModesCount;
|
int blendModesCount;
|
||||||
D3D11_BlendMode *blendModes;
|
D3D11_BlendMode *blendModes;
|
||||||
ID3D11SamplerState *samplers[D3D11_SAMPLER_COUNT];
|
ID3D11SamplerState *samplers[RENDER_SAMPLER_COUNT];
|
||||||
D3D_FEATURE_LEVEL featureLevel;
|
D3D_FEATURE_LEVEL featureLevel;
|
||||||
bool pixelSizeChanged;
|
bool pixelSizeChanged;
|
||||||
|
|
||||||
|
@ -538,7 +528,6 @@ static HRESULT D3D11_CreateDeviceResources(SDL_Renderer *renderer)
|
||||||
};
|
};
|
||||||
|
|
||||||
D3D11_BUFFER_DESC constantBufferDesc;
|
D3D11_BUFFER_DESC constantBufferDesc;
|
||||||
D3D11_SAMPLER_DESC samplerDesc;
|
|
||||||
D3D11_RASTERIZER_DESC rasterDesc;
|
D3D11_RASTERIZER_DESC rasterDesc;
|
||||||
|
|
||||||
// See if we need debug interfaces
|
// See if we need debug interfaces
|
||||||
|
@ -727,38 +716,6 @@ static HRESULT D3D11_CreateDeviceResources(SDL_Renderer *renderer)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create samplers to use when drawing textures:
|
|
||||||
static struct
|
|
||||||
{
|
|
||||||
D3D11_FILTER filter;
|
|
||||||
D3D11_TEXTURE_ADDRESS_MODE address;
|
|
||||||
} samplerParams[] = {
|
|
||||||
{ D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_CLAMP },
|
|
||||||
{ D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_WRAP },
|
|
||||||
{ D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_CLAMP },
|
|
||||||
{ D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_WRAP },
|
|
||||||
};
|
|
||||||
SDL_COMPILE_TIME_ASSERT(samplerParams_SIZE, SDL_arraysize(samplerParams) == D3D11_SAMPLER_COUNT);
|
|
||||||
SDL_zero(samplerDesc);
|
|
||||||
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
|
||||||
samplerDesc.MipLODBias = 0.0f;
|
|
||||||
samplerDesc.MaxAnisotropy = 1;
|
|
||||||
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
|
||||||
samplerDesc.MinLOD = 0.0f;
|
|
||||||
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
|
|
||||||
for (int i = 0; i < SDL_arraysize(samplerParams); ++i) {
|
|
||||||
samplerDesc.Filter = samplerParams[i].filter;
|
|
||||||
samplerDesc.AddressU = samplerParams[i].address;
|
|
||||||
samplerDesc.AddressV = samplerParams[i].address;
|
|
||||||
result = ID3D11Device_CreateSamplerState(data->d3dDevice,
|
|
||||||
&samplerDesc,
|
|
||||||
&data->samplers[i]);
|
|
||||||
if (FAILED(result)) {
|
|
||||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateSamplerState [nearest-pixel filter]"), result);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup Direct3D rasterizer states
|
// Setup Direct3D rasterizer states
|
||||||
SDL_zero(rasterDesc);
|
SDL_zero(rasterDesc);
|
||||||
rasterDesc.AntialiasedLineEnable = FALSE;
|
rasterDesc.AntialiasedLineEnable = FALSE;
|
||||||
|
@ -2305,6 +2262,64 @@ static bool D3D11_SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ID3D11SamplerState *D3D11_GetSamplerState(D3D11_RenderData *data, SDL_ScaleMode scale_mode, SDL_TextureAddressMode address_u, SDL_TextureAddressMode address_v)
|
||||||
|
{
|
||||||
|
Uint32 key = RENDER_SAMPLER_HASHKEY(scale_mode, address_u, address_v);
|
||||||
|
SDL_assert(key < SDL_arraysize(data->samplers));
|
||||||
|
if (!data->samplers[key]) {
|
||||||
|
D3D11_SAMPLER_DESC samplerDesc;
|
||||||
|
SDL_zero(samplerDesc);
|
||||||
|
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
samplerDesc.MipLODBias = 0.0f;
|
||||||
|
samplerDesc.MaxAnisotropy = 1;
|
||||||
|
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||||
|
samplerDesc.MinLOD = 0.0f;
|
||||||
|
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
|
||||||
|
switch (scale_mode) {
|
||||||
|
case SDL_SCALEMODE_NEAREST:
|
||||||
|
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||||
|
break;
|
||||||
|
case SDL_SCALEMODE_PIXELART: // Uses linear sampling
|
||||||
|
case SDL_SCALEMODE_LINEAR:
|
||||||
|
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_SetError("Unknown scale mode: %d", scale_mode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
switch (address_u) {
|
||||||
|
case SDL_TEXTURE_ADDRESS_CLAMP:
|
||||||
|
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
break;
|
||||||
|
case SDL_TEXTURE_ADDRESS_WRAP:
|
||||||
|
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_SetError("Unknown texture address mode: %d", address_u);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
switch (address_v) {
|
||||||
|
case SDL_TEXTURE_ADDRESS_CLAMP:
|
||||||
|
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
break;
|
||||||
|
case SDL_TEXTURE_ADDRESS_WRAP:
|
||||||
|
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_SetError("Unknown texture address mode: %d", address_v);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
HRESULT result = ID3D11Device_CreateSamplerState(data->d3dDevice,
|
||||||
|
&samplerDesc,
|
||||||
|
&data->samplers[key]);
|
||||||
|
if (FAILED(result)) {
|
||||||
|
WIN_SetErrorFromHRESULT("ID3D11Device::CreateSamplerState", result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data->samplers[key];
|
||||||
|
}
|
||||||
|
|
||||||
static bool D3D11_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const Float4X4 *matrix)
|
static bool D3D11_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const Float4X4 *matrix)
|
||||||
{
|
{
|
||||||
SDL_Texture *texture = cmd->data.draw.texture;
|
SDL_Texture *texture = cmd->data.draw.texture;
|
||||||
|
@ -2319,35 +2334,11 @@ static bool D3D11_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *
|
||||||
|
|
||||||
D3D11_SetupShaderConstants(renderer, cmd, texture, &constants);
|
D3D11_SetupShaderConstants(renderer, cmd, texture, &constants);
|
||||||
|
|
||||||
switch (cmd->data.draw.texture_scale_mode) {
|
textureSampler = D3D11_GetSamplerState(rendererData, cmd->data.draw.texture_scale_mode, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
|
||||||
case SDL_SCALEMODE_NEAREST:
|
if (!textureSampler) {
|
||||||
switch (cmd->data.draw.texture_address_mode) {
|
return false;
|
||||||
case SDL_TEXTURE_ADDRESS_CLAMP:
|
|
||||||
textureSampler = rendererData->samplers[D3D11_SAMPLER_NEAREST_CLAMP];
|
|
||||||
break;
|
|
||||||
case SDL_TEXTURE_ADDRESS_WRAP:
|
|
||||||
textureSampler = rendererData->samplers[D3D11_SAMPLER_NEAREST_WRAP];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return SDL_SetError("Unknown texture address mode: %d", cmd->data.draw.texture_address_mode);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SDL_SCALEMODE_PIXELART: // Uses linear sampling
|
|
||||||
case SDL_SCALEMODE_LINEAR:
|
|
||||||
switch (cmd->data.draw.texture_address_mode) {
|
|
||||||
case SDL_TEXTURE_ADDRESS_CLAMP:
|
|
||||||
textureSampler = rendererData->samplers[D3D11_SAMPLER_LINEAR_CLAMP];
|
|
||||||
break;
|
|
||||||
case SDL_TEXTURE_ADDRESS_WRAP:
|
|
||||||
textureSampler = rendererData->samplers[D3D11_SAMPLER_LINEAR_WRAP];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return SDL_SetError("Unknown texture address mode: %d", cmd->data.draw.texture_address_mode);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return SDL_SetError("Unknown scale mode: %d", cmd->data.draw.texture_scale_mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SDL_HAVE_YUV
|
#ifdef SDL_HAVE_YUV
|
||||||
if (textureData->yuv) {
|
if (textureData->yuv) {
|
||||||
ID3D11ShaderResourceView *shaderResources[3];
|
ID3D11ShaderResourceView *shaderResources[3];
|
||||||
|
|
|
@ -56,16 +56,6 @@ extern "C" {
|
||||||
/* !!! FIXME: vertex buffer bandwidth could be lower; only use UV coords when
|
/* !!! FIXME: vertex buffer bandwidth could be lower; only use UV coords when
|
||||||
!!! FIXME: textures are needed. */
|
!!! FIXME: textures are needed. */
|
||||||
|
|
||||||
// Sampler types
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
D3D12_SAMPLER_NEAREST_CLAMP,
|
|
||||||
D3D12_SAMPLER_NEAREST_WRAP,
|
|
||||||
D3D12_SAMPLER_LINEAR_CLAMP,
|
|
||||||
D3D12_SAMPLER_LINEAR_WRAP,
|
|
||||||
D3D12_SAMPLER_COUNT
|
|
||||||
} D3D12_Sampler;
|
|
||||||
|
|
||||||
// Vertex shader, common values
|
// Vertex shader, common values
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -231,7 +221,8 @@ typedef struct
|
||||||
D3D12_PipelineState *currentPipelineState;
|
D3D12_PipelineState *currentPipelineState;
|
||||||
|
|
||||||
D3D12_VertexBuffer vertexBuffers[SDL_D3D12_NUM_VERTEX_BUFFERS];
|
D3D12_VertexBuffer vertexBuffers[SDL_D3D12_NUM_VERTEX_BUFFERS];
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE samplers[D3D12_SAMPLER_COUNT];
|
D3D12_CPU_DESCRIPTOR_HANDLE samplers[RENDER_SAMPLER_COUNT];
|
||||||
|
bool samplers_created[RENDER_SAMPLER_COUNT];
|
||||||
|
|
||||||
// Data for staging/allocating textures
|
// Data for staging/allocating textures
|
||||||
ID3D12Resource *uploadBuffers[SDL_D3D12_NUM_UPLOAD_BUFFERS];
|
ID3D12Resource *uploadBuffers[SDL_D3D12_NUM_UPLOAD_BUFFERS];
|
||||||
|
@ -419,6 +410,7 @@ static void D3D12_ReleaseAll(SDL_Renderer *renderer)
|
||||||
D3D_SAFE_RELEASE(data->textureRTVDescriptorHeap);
|
D3D_SAFE_RELEASE(data->textureRTVDescriptorHeap);
|
||||||
D3D_SAFE_RELEASE(data->srvDescriptorHeap);
|
D3D_SAFE_RELEASE(data->srvDescriptorHeap);
|
||||||
D3D_SAFE_RELEASE(data->samplerDescriptorHeap);
|
D3D_SAFE_RELEASE(data->samplerDescriptorHeap);
|
||||||
|
SDL_zeroa(data->samplers_created);
|
||||||
D3D_SAFE_RELEASE(data->fence);
|
D3D_SAFE_RELEASE(data->fence);
|
||||||
|
|
||||||
for (i = 0; i < SDL_D3D12_NUM_BUFFERS; ++i) {
|
for (i = 0; i < SDL_D3D12_NUM_BUFFERS; ++i) {
|
||||||
|
@ -796,7 +788,6 @@ static HRESULT D3D12_CreateDeviceResources(SDL_Renderer *renderer)
|
||||||
|
|
||||||
D3D12_COMMAND_QUEUE_DESC queueDesc;
|
D3D12_COMMAND_QUEUE_DESC queueDesc;
|
||||||
D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapDesc;
|
D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapDesc;
|
||||||
D3D12_SAMPLER_DESC samplerDesc;
|
|
||||||
ID3D12DescriptorHeap *rootDescriptorHeaps[2];
|
ID3D12DescriptorHeap *rootDescriptorHeaps[2];
|
||||||
|
|
||||||
// See if we need debug interfaces
|
// See if we need debug interfaces
|
||||||
|
@ -1114,31 +1105,9 @@ static HRESULT D3D12_CreateDeviceResources(SDL_Renderer *renderer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create samplers to use when drawing textures:
|
// Create samplers to use when drawing textures:
|
||||||
static struct
|
|
||||||
{
|
|
||||||
D3D12_FILTER filter;
|
|
||||||
D3D12_TEXTURE_ADDRESS_MODE address;
|
|
||||||
} samplerParams[] = {
|
|
||||||
{ D3D12_FILTER_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_CLAMP },
|
|
||||||
{ D3D12_FILTER_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_WRAP },
|
|
||||||
{ D3D12_FILTER_MIN_MAG_MIP_LINEAR, D3D12_TEXTURE_ADDRESS_MODE_CLAMP },
|
|
||||||
{ D3D12_FILTER_MIN_MAG_MIP_LINEAR, D3D12_TEXTURE_ADDRESS_MODE_WRAP },
|
|
||||||
};
|
|
||||||
SDL_COMPILE_TIME_ASSERT(samplerParams_SIZE, SDL_arraysize(samplerParams) == D3D12_SAMPLER_COUNT);
|
|
||||||
SDL_zero(samplerDesc);
|
|
||||||
samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
|
||||||
samplerDesc.MipLODBias = 0.0f;
|
|
||||||
samplerDesc.MaxAnisotropy = 1;
|
|
||||||
samplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
|
|
||||||
samplerDesc.MinLOD = 0.0f;
|
|
||||||
samplerDesc.MaxLOD = D3D12_FLOAT32_MAX;
|
|
||||||
D3D_CALL_RET(data->samplerDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &data->samplers[0]);
|
D3D_CALL_RET(data->samplerDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &data->samplers[0]);
|
||||||
for (i = 0; i < SDL_arraysize(samplerParams); ++i) {
|
for (i = 0; i < SDL_arraysize(data->samplers); ++i) {
|
||||||
samplerDesc.Filter = samplerParams[i].filter;
|
|
||||||
samplerDesc.AddressU = samplerParams[i].address;
|
|
||||||
samplerDesc.AddressV = samplerParams[i].address;
|
|
||||||
data->samplers[i].ptr = data->samplers[0].ptr + i * data->samplerDescriptorSize;
|
data->samplers[i].ptr = data->samplers[0].ptr + i * data->samplerDescriptorSize;
|
||||||
ID3D12Device1_CreateSampler(data->d3dDevice, &samplerDesc, data->samplers[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the pool allocator for SRVs
|
// Initialize the pool allocator for SRVs
|
||||||
|
@ -2743,6 +2712,59 @@ static bool D3D12_SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static D3D12_CPU_DESCRIPTOR_HANDLE *D3D12_GetSamplerState(D3D12_RenderData *data, SDL_ScaleMode scale_mode, SDL_TextureAddressMode address_u, SDL_TextureAddressMode address_v)
|
||||||
|
{
|
||||||
|
Uint32 key = RENDER_SAMPLER_HASHKEY(scale_mode, address_u, address_v);
|
||||||
|
SDL_assert(key < SDL_arraysize(data->samplers));
|
||||||
|
if (!data->samplers_created[key]) {
|
||||||
|
D3D12_SAMPLER_DESC samplerDesc;
|
||||||
|
SDL_zero(samplerDesc);
|
||||||
|
samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||||
|
samplerDesc.MipLODBias = 0.0f;
|
||||||
|
samplerDesc.MaxAnisotropy = 1;
|
||||||
|
samplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
|
||||||
|
samplerDesc.MinLOD = 0.0f;
|
||||||
|
samplerDesc.MaxLOD = D3D12_FLOAT32_MAX;
|
||||||
|
switch (scale_mode) {
|
||||||
|
case SDL_SCALEMODE_NEAREST:
|
||||||
|
samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
|
||||||
|
break;
|
||||||
|
case SDL_SCALEMODE_PIXELART: // Uses linear sampling
|
||||||
|
case SDL_SCALEMODE_LINEAR:
|
||||||
|
samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_SetError("Unknown scale mode: %d", scale_mode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
switch (address_u) {
|
||||||
|
case SDL_TEXTURE_ADDRESS_CLAMP:
|
||||||
|
samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||||
|
break;
|
||||||
|
case SDL_TEXTURE_ADDRESS_WRAP:
|
||||||
|
samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_SetError("Unknown texture address mode: %d", address_u);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
switch (address_v) {
|
||||||
|
case SDL_TEXTURE_ADDRESS_CLAMP:
|
||||||
|
samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||||
|
break;
|
||||||
|
case SDL_TEXTURE_ADDRESS_WRAP:
|
||||||
|
samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_SetError("Unknown texture address mode: %d", address_v);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ID3D12Device1_CreateSampler(data->d3dDevice, &samplerDesc, data->samplers[key]);
|
||||||
|
data->samplers_created[key] = true;
|
||||||
|
}
|
||||||
|
return &data->samplers[key];
|
||||||
|
}
|
||||||
|
|
||||||
static bool D3D12_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const Float4X4 *matrix)
|
static bool D3D12_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const Float4X4 *matrix)
|
||||||
{
|
{
|
||||||
SDL_Texture *texture = cmd->data.draw.texture;
|
SDL_Texture *texture = cmd->data.draw.texture;
|
||||||
|
@ -2757,35 +2779,11 @@ static bool D3D12_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *
|
||||||
|
|
||||||
D3D12_SetupShaderConstants(renderer, cmd, texture, &constants);
|
D3D12_SetupShaderConstants(renderer, cmd, texture, &constants);
|
||||||
|
|
||||||
switch (cmd->data.draw.texture_scale_mode) {
|
textureSampler = D3D12_GetSamplerState(rendererData, cmd->data.draw.texture_scale_mode, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
|
||||||
case SDL_SCALEMODE_NEAREST:
|
if (!textureSampler) {
|
||||||
switch (cmd->data.draw.texture_address_mode) {
|
return false;
|
||||||
case SDL_TEXTURE_ADDRESS_CLAMP:
|
|
||||||
textureSampler = &rendererData->samplers[D3D12_SAMPLER_NEAREST_CLAMP];
|
|
||||||
break;
|
|
||||||
case SDL_TEXTURE_ADDRESS_WRAP:
|
|
||||||
textureSampler = &rendererData->samplers[D3D12_SAMPLER_NEAREST_WRAP];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return SDL_SetError("Unknown texture address mode: %d", cmd->data.draw.texture_address_mode);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SDL_SCALEMODE_PIXELART: // Uses linear sampling
|
|
||||||
case SDL_SCALEMODE_LINEAR:
|
|
||||||
switch (cmd->data.draw.texture_address_mode) {
|
|
||||||
case SDL_TEXTURE_ADDRESS_CLAMP:
|
|
||||||
textureSampler = &rendererData->samplers[D3D12_SAMPLER_LINEAR_CLAMP];
|
|
||||||
break;
|
|
||||||
case SDL_TEXTURE_ADDRESS_WRAP:
|
|
||||||
textureSampler = &rendererData->samplers[D3D12_SAMPLER_LINEAR_WRAP];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return SDL_SetError("Unknown texture address mode: %d", cmd->data.draw.texture_address_mode);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return SDL_SetError("Unknown scale mode: %d", cmd->data.draw.texture_scale_mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SDL_HAVE_YUV
|
#ifdef SDL_HAVE_YUV
|
||||||
if (textureData->yuv) {
|
if (textureData->yuv) {
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE shaderResources[3];
|
D3D12_CPU_DESCRIPTOR_HANDLE shaderResources[3];
|
||||||
|
|
|
@ -83,7 +83,7 @@ typedef struct GPU_RenderData
|
||||||
bool scissor_was_enabled;
|
bool scissor_was_enabled;
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
SDL_GPUSampler *samplers[3][2];
|
SDL_GPUSampler *samplers[RENDER_SAMPLER_COUNT];
|
||||||
} GPU_RenderData;
|
} GPU_RenderData;
|
||||||
|
|
||||||
typedef struct GPU_TextureData
|
typedef struct GPU_TextureData
|
||||||
|
@ -505,13 +505,6 @@ static void PushFragmentUniforms(GPU_RenderData *data, SDL_RenderCommand *cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_GPUSampler **SamplerPointer(GPU_RenderData *data, SDL_TextureAddressMode address_mode, SDL_ScaleMode scale_mode)
|
|
||||||
{
|
|
||||||
SDL_assert(scale_mode < SDL_arraysize(data->samplers));
|
|
||||||
SDL_assert((address_mode - 1) < SDL_arraysize(data->samplers[0]));
|
|
||||||
return &data->samplers[scale_mode][address_mode - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SetViewportAndScissor(GPU_RenderData *data)
|
static void SetViewportAndScissor(GPU_RenderData *data)
|
||||||
{
|
{
|
||||||
SDL_SetGPUViewport(data->state.render_pass, &data->state.viewport);
|
SDL_SetGPUViewport(data->state.render_pass, &data->state.viewport);
|
||||||
|
@ -530,6 +523,58 @@ static void SetViewportAndScissor(GPU_RenderData *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SDL_GPUSampler *GetSampler(GPU_RenderData *data, SDL_ScaleMode scale_mode, SDL_TextureAddressMode address_u, SDL_TextureAddressMode address_v)
|
||||||
|
{
|
||||||
|
Uint32 key = RENDER_SAMPLER_HASHKEY(scale_mode, address_u, address_v);
|
||||||
|
SDL_assert(key < SDL_arraysize(data->samplers));
|
||||||
|
if (!data->samplers[key]) {
|
||||||
|
SDL_GPUSamplerCreateInfo sci;
|
||||||
|
SDL_zero(sci);
|
||||||
|
switch (scale_mode) {
|
||||||
|
case SDL_SCALEMODE_NEAREST:
|
||||||
|
sci.min_filter = SDL_GPU_FILTER_NEAREST;
|
||||||
|
sci.mag_filter = SDL_GPU_FILTER_NEAREST;
|
||||||
|
sci.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_NEAREST;
|
||||||
|
break;
|
||||||
|
case SDL_SCALEMODE_PIXELART: // Uses linear sampling
|
||||||
|
case SDL_SCALEMODE_LINEAR:
|
||||||
|
sci.min_filter = SDL_GPU_FILTER_LINEAR;
|
||||||
|
sci.mag_filter = SDL_GPU_FILTER_LINEAR;
|
||||||
|
sci.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_SetError("Unknown scale mode: %d", scale_mode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
switch (address_u) {
|
||||||
|
case SDL_TEXTURE_ADDRESS_CLAMP:
|
||||||
|
sci.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||||
|
break;
|
||||||
|
case SDL_TEXTURE_ADDRESS_WRAP:
|
||||||
|
sci.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_REPEAT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_SetError("Unknown texture address mode: %d", address_u);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
switch (address_v) {
|
||||||
|
case SDL_TEXTURE_ADDRESS_CLAMP:
|
||||||
|
sci.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||||
|
break;
|
||||||
|
case SDL_TEXTURE_ADDRESS_WRAP:
|
||||||
|
sci.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_REPEAT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_SetError("Unknown texture address mode: %d", address_v);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
sci.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||||
|
|
||||||
|
data->samplers[key] = SDL_CreateGPUSampler(data->device, &sci);
|
||||||
|
}
|
||||||
|
return data->samplers[key];
|
||||||
|
}
|
||||||
|
|
||||||
static void Draw(
|
static void Draw(
|
||||||
GPU_RenderData *data, SDL_RenderCommand *cmd,
|
GPU_RenderData *data, SDL_RenderCommand *cmd,
|
||||||
Uint32 num_verts,
|
Uint32 num_verts,
|
||||||
|
@ -603,7 +648,7 @@ static void Draw(
|
||||||
GPU_TextureData *tdata = (GPU_TextureData *)cmd->data.draw.texture->internal;
|
GPU_TextureData *tdata = (GPU_TextureData *)cmd->data.draw.texture->internal;
|
||||||
SDL_GPUTextureSamplerBinding sampler_bind;
|
SDL_GPUTextureSamplerBinding sampler_bind;
|
||||||
SDL_zero(sampler_bind);
|
SDL_zero(sampler_bind);
|
||||||
sampler_bind.sampler = *SamplerPointer(data, cmd->data.draw.texture_address_mode, cmd->data.draw.texture_scale_mode);
|
sampler_bind.sampler = GetSampler(data, cmd->data.draw.texture_scale_mode, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
|
||||||
sampler_bind.texture = tdata->texture;
|
sampler_bind.texture = tdata->texture;
|
||||||
SDL_BindGPUFragmentSamplers(pass, sampler_slot++, &sampler_bind, 1);
|
SDL_BindGPUFragmentSamplers(pass, sampler_slot++, &sampler_bind, 1);
|
||||||
}
|
}
|
||||||
|
@ -835,7 +880,8 @@ static bool GPU_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||||
SDL_Texture *thistexture = cmd->data.draw.texture;
|
SDL_Texture *thistexture = cmd->data.draw.texture;
|
||||||
SDL_BlendMode thisblend = cmd->data.draw.blend;
|
SDL_BlendMode thisblend = cmd->data.draw.blend;
|
||||||
SDL_ScaleMode thisscalemode = cmd->data.draw.texture_scale_mode;
|
SDL_ScaleMode thisscalemode = cmd->data.draw.texture_scale_mode;
|
||||||
SDL_TextureAddressMode thisaddressmode = cmd->data.draw.texture_address_mode;
|
SDL_TextureAddressMode thisaddressmode_u = cmd->data.draw.texture_address_mode_u;
|
||||||
|
SDL_TextureAddressMode thisaddressmode_v = cmd->data.draw.texture_address_mode_v;
|
||||||
const SDL_RenderCommandType thiscmdtype = cmd->command;
|
const SDL_RenderCommandType thiscmdtype = cmd->command;
|
||||||
SDL_RenderCommand *finalcmd = cmd;
|
SDL_RenderCommand *finalcmd = cmd;
|
||||||
SDL_RenderCommand *nextcmd = cmd->next;
|
SDL_RenderCommand *nextcmd = cmd->next;
|
||||||
|
@ -848,7 +894,8 @@ static bool GPU_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||||
break; // can't go any further on this draw call, different render command up next.
|
break; // can't go any further on this draw call, different render command up next.
|
||||||
} else if (nextcmd->data.draw.texture != thistexture ||
|
} else if (nextcmd->data.draw.texture != thistexture ||
|
||||||
nextcmd->data.draw.texture_scale_mode != thisscalemode ||
|
nextcmd->data.draw.texture_scale_mode != thisscalemode ||
|
||||||
nextcmd->data.draw.texture_address_mode != thisaddressmode ||
|
nextcmd->data.draw.texture_address_mode_u != thisaddressmode_u ||
|
||||||
|
nextcmd->data.draw.texture_address_mode_v != thisaddressmode_v ||
|
||||||
nextcmd->data.draw.blend != thisblend) {
|
nextcmd->data.draw.blend != thisblend) {
|
||||||
// FIXME should we check address mode too?
|
// FIXME should we check address mode too?
|
||||||
break; // can't go any further on this draw call, different texture/blendmode copy up next.
|
break; // can't go any further on this draw call, different texture/blendmode copy up next.
|
||||||
|
@ -1080,8 +1127,8 @@ static void GPU_DestroyRenderer(SDL_Renderer *renderer)
|
||||||
data->state.command_buffer = NULL;
|
data->state.command_buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Uint32 i = 0; i < sizeof(data->samplers) / sizeof(SDL_GPUSampler *); ++i) {
|
for (Uint32 i = 0; i < SDL_arraysize(data->samplers); ++i) {
|
||||||
SDL_ReleaseGPUSampler(data->device, ((SDL_GPUSampler **)data->samplers)[i]);
|
SDL_ReleaseGPUSampler(data->device, data->samplers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->backbuffer.texture) {
|
if (data->backbuffer.texture) {
|
||||||
|
@ -1153,70 +1200,6 @@ static bool GPU_SetVSync(SDL_Renderer *renderer, const int vsync)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool InitSamplers(GPU_RenderData *data)
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
SDL_TextureAddressMode address_mode;
|
|
||||||
SDL_ScaleMode scale_mode;
|
|
||||||
} sdl;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
SDL_GPUSamplerAddressMode address_mode;
|
|
||||||
SDL_GPUFilter filter;
|
|
||||||
SDL_GPUSamplerMipmapMode mipmap_mode;
|
|
||||||
Uint32 anisotropy;
|
|
||||||
} gpu;
|
|
||||||
} configs[] = {
|
|
||||||
{
|
|
||||||
{ SDL_TEXTURE_ADDRESS_CLAMP, SDL_SCALEMODE_NEAREST },
|
|
||||||
{ SDL_GPU_SAMPLERADDRESSMODE_REPEAT, SDL_GPU_FILTER_NEAREST, SDL_GPU_SAMPLERMIPMAPMODE_NEAREST, 0 },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{ SDL_TEXTURE_ADDRESS_CLAMP, SDL_SCALEMODE_LINEAR },
|
|
||||||
{ SDL_GPU_SAMPLERADDRESSMODE_REPEAT, SDL_GPU_FILTER_LINEAR, SDL_GPU_SAMPLERMIPMAPMODE_LINEAR, 0 },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{ SDL_TEXTURE_ADDRESS_CLAMP, SDL_SCALEMODE_PIXELART },
|
|
||||||
{ SDL_GPU_SAMPLERADDRESSMODE_REPEAT, SDL_GPU_FILTER_NEAREST, SDL_GPU_SAMPLERMIPMAPMODE_NEAREST, 0 },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{ SDL_TEXTURE_ADDRESS_WRAP, SDL_SCALEMODE_NEAREST },
|
|
||||||
{ SDL_GPU_SAMPLERADDRESSMODE_REPEAT, SDL_GPU_FILTER_NEAREST, SDL_GPU_SAMPLERMIPMAPMODE_NEAREST, 0 },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{ SDL_TEXTURE_ADDRESS_WRAP, SDL_SCALEMODE_LINEAR },
|
|
||||||
{ SDL_GPU_SAMPLERADDRESSMODE_REPEAT, SDL_GPU_FILTER_LINEAR, SDL_GPU_SAMPLERMIPMAPMODE_LINEAR, 0 },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{ SDL_TEXTURE_ADDRESS_WRAP, SDL_SCALEMODE_PIXELART },
|
|
||||||
{ SDL_GPU_SAMPLERADDRESSMODE_REPEAT, SDL_GPU_FILTER_NEAREST, SDL_GPU_SAMPLERMIPMAPMODE_NEAREST, 0 },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (Uint32 i = 0; i < SDL_arraysize(configs); ++i) {
|
|
||||||
SDL_GPUSamplerCreateInfo sci;
|
|
||||||
SDL_zero(sci);
|
|
||||||
sci.max_anisotropy = configs[i].gpu.anisotropy;
|
|
||||||
sci.enable_anisotropy = configs[i].gpu.anisotropy > 0;
|
|
||||||
sci.address_mode_u = sci.address_mode_v = sci.address_mode_w = configs[i].gpu.address_mode;
|
|
||||||
sci.min_filter = sci.mag_filter = configs[i].gpu.filter;
|
|
||||||
sci.mipmap_mode = configs[i].gpu.mipmap_mode;
|
|
||||||
|
|
||||||
SDL_GPUSampler *sampler = SDL_CreateGPUSampler(data->device, &sci);
|
|
||||||
|
|
||||||
if (sampler == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
*SamplerPointer(data, configs[i].sdl.address_mode, configs[i].sdl.scale_mode) = sampler;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool GPU_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
|
static bool GPU_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
|
||||||
{
|
{
|
||||||
GPU_RenderData *data = NULL;
|
GPU_RenderData *data = NULL;
|
||||||
|
@ -1285,10 +1268,6 @@ static bool GPU_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_P
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!InitSamplers(data)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SDL_ClaimWindowForGPUDevice(data->device, window)) {
|
if (!SDL_ClaimWindowForGPUDevice(data->device, window)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,16 +79,6 @@ static const size_t CONSTANTS_OFFSET_DECODE_BT2020_LIMITED = ALIGN_CONSTANTS(16,
|
||||||
static const size_t CONSTANTS_OFFSET_DECODE_BT2020_FULL = ALIGN_CONSTANTS(16, CONSTANTS_OFFSET_DECODE_BT2020_LIMITED + sizeof(float) * 4 * 4);
|
static const size_t CONSTANTS_OFFSET_DECODE_BT2020_FULL = ALIGN_CONSTANTS(16, CONSTANTS_OFFSET_DECODE_BT2020_LIMITED + sizeof(float) * 4 * 4);
|
||||||
static const size_t CONSTANTS_LENGTH = CONSTANTS_OFFSET_DECODE_BT2020_FULL + sizeof(float) * 4 * 4;
|
static const size_t CONSTANTS_LENGTH = CONSTANTS_OFFSET_DECODE_BT2020_FULL + sizeof(float) * 4 * 4;
|
||||||
|
|
||||||
// Sampler types
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
SDL_METAL_SAMPLER_NEAREST_CLAMP,
|
|
||||||
SDL_METAL_SAMPLER_NEAREST_WRAP,
|
|
||||||
SDL_METAL_SAMPLER_LINEAR_CLAMP,
|
|
||||||
SDL_METAL_SAMPLER_LINEAR_WRAP,
|
|
||||||
SDL_NUM_METAL_SAMPLERS
|
|
||||||
} SDL_METAL_sampler_type;
|
|
||||||
|
|
||||||
typedef enum SDL_MetalVertexFunction
|
typedef enum SDL_MetalVertexFunction
|
||||||
{
|
{
|
||||||
SDL_METAL_VERTEX_SOLID,
|
SDL_METAL_VERTEX_SOLID,
|
||||||
|
@ -139,7 +129,7 @@ typedef struct METAL_ShaderPipelines
|
||||||
@property(nonatomic, retain) id<MTLRenderCommandEncoder> mtlcmdencoder;
|
@property(nonatomic, retain) id<MTLRenderCommandEncoder> mtlcmdencoder;
|
||||||
@property(nonatomic, retain) id<MTLLibrary> mtllibrary;
|
@property(nonatomic, retain) id<MTLLibrary> mtllibrary;
|
||||||
@property(nonatomic, retain) id<CAMetalDrawable> mtlbackbuffer;
|
@property(nonatomic, retain) id<CAMetalDrawable> mtlbackbuffer;
|
||||||
@property(nonatomic, retain) NSMutableArray<id<MTLSamplerState>> *mtlsamplers;
|
@property(nonatomic, retain) NSMutableDictionary<NSNumber *, id<MTLSamplerState>> *mtlsamplers;
|
||||||
@property(nonatomic, retain) id<MTLBuffer> mtlbufconstants;
|
@property(nonatomic, retain) id<MTLBuffer> mtlbufconstants;
|
||||||
@property(nonatomic, retain) id<MTLBuffer> mtlbufquadindices;
|
@property(nonatomic, retain) id<MTLBuffer> mtlbufquadindices;
|
||||||
@property(nonatomic, assign) SDL_MetalView mtlview;
|
@property(nonatomic, assign) SDL_MetalView mtlview;
|
||||||
|
@ -1301,6 +1291,9 @@ typedef struct
|
||||||
__unsafe_unretained id<MTLBuffer> vertex_buffer;
|
__unsafe_unretained id<MTLBuffer> vertex_buffer;
|
||||||
size_t constants_offset;
|
size_t constants_offset;
|
||||||
SDL_Texture *texture;
|
SDL_Texture *texture;
|
||||||
|
SDL_ScaleMode texture_scale_mode;
|
||||||
|
SDL_TextureAddressMode texture_address_mode_u;
|
||||||
|
SDL_TextureAddressMode texture_address_mode_v;
|
||||||
bool cliprect_dirty;
|
bool cliprect_dirty;
|
||||||
bool cliprect_enabled;
|
bool cliprect_enabled;
|
||||||
SDL_Rect cliprect;
|
SDL_Rect cliprect;
|
||||||
|
@ -1466,6 +1459,59 @@ static bool SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, c
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static id<MTLSamplerState> GetSampler(SDL3METAL_RenderData *data, SDL_ScaleMode scale_mode, SDL_TextureAddressMode address_u, SDL_TextureAddressMode address_v)
|
||||||
|
{
|
||||||
|
NSNumber *key = [NSNumber numberWithInteger:RENDER_SAMPLER_HASHKEY(scale_mode, address_u, address_v)];
|
||||||
|
id<MTLSamplerState> mtlsampler = data.mtlsamplers[key];
|
||||||
|
if (mtlsampler == nil) {
|
||||||
|
MTLSamplerDescriptor *samplerdesc;
|
||||||
|
samplerdesc = [[MTLSamplerDescriptor alloc] init];
|
||||||
|
switch (scale_mode) {
|
||||||
|
case SDL_SCALEMODE_NEAREST:
|
||||||
|
samplerdesc.minFilter = MTLSamplerMinMagFilterNearest;
|
||||||
|
samplerdesc.magFilter = MTLSamplerMinMagFilterNearest;
|
||||||
|
break;
|
||||||
|
case SDL_SCALEMODE_PIXELART: // Uses linear sampling
|
||||||
|
case SDL_SCALEMODE_LINEAR:
|
||||||
|
samplerdesc.minFilter = MTLSamplerMinMagFilterLinear;
|
||||||
|
samplerdesc.magFilter = MTLSamplerMinMagFilterLinear;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_SetError("Unknown scale mode: %d", scale_mode);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
switch (address_u) {
|
||||||
|
case SDL_TEXTURE_ADDRESS_CLAMP:
|
||||||
|
samplerdesc.sAddressMode = MTLSamplerAddressModeClampToEdge;
|
||||||
|
break;
|
||||||
|
case SDL_TEXTURE_ADDRESS_WRAP:
|
||||||
|
samplerdesc.sAddressMode = MTLSamplerAddressModeRepeat;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_SetError("Unknown texture address mode: %d", address_u);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
switch (address_v) {
|
||||||
|
case SDL_TEXTURE_ADDRESS_CLAMP:
|
||||||
|
samplerdesc.tAddressMode = MTLSamplerAddressModeClampToEdge;
|
||||||
|
break;
|
||||||
|
case SDL_TEXTURE_ADDRESS_WRAP:
|
||||||
|
samplerdesc.tAddressMode = MTLSamplerAddressModeRepeat;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_SetError("Unknown texture address mode: %d", address_v);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
mtlsampler = [data.mtldevice newSamplerStateWithDescriptor:samplerdesc];
|
||||||
|
if (mtlsampler == nil) {
|
||||||
|
SDL_SetError("Couldn't create sampler");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
data.mtlsamplers[key] = mtlsampler;
|
||||||
|
}
|
||||||
|
return mtlsampler;
|
||||||
|
}
|
||||||
|
|
||||||
static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t constants_offset,
|
static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t constants_offset,
|
||||||
id<MTLBuffer> mtlbufvertex, METAL_DrawStateCache *statecache)
|
id<MTLBuffer> mtlbufvertex, METAL_DrawStateCache *statecache)
|
||||||
{
|
{
|
||||||
|
@ -1481,33 +1527,6 @@ static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, c
|
||||||
}
|
}
|
||||||
|
|
||||||
if (texture != statecache->texture) {
|
if (texture != statecache->texture) {
|
||||||
id<MTLSamplerState> mtlsampler;
|
|
||||||
|
|
||||||
if (cmd->data.draw.texture_scale_mode == SDL_SCALEMODE_NEAREST) {
|
|
||||||
switch (cmd->data.draw.texture_address_mode) {
|
|
||||||
case SDL_TEXTURE_ADDRESS_CLAMP:
|
|
||||||
mtlsampler = data.mtlsamplers[SDL_METAL_SAMPLER_NEAREST_CLAMP];
|
|
||||||
break;
|
|
||||||
case SDL_TEXTURE_ADDRESS_WRAP:
|
|
||||||
mtlsampler = data.mtlsamplers[SDL_METAL_SAMPLER_NEAREST_WRAP];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return SDL_SetError("Unknown texture address mode: %d", cmd->data.draw.texture_address_mode);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (cmd->data.draw.texture_address_mode) {
|
|
||||||
case SDL_TEXTURE_ADDRESS_CLAMP:
|
|
||||||
mtlsampler = data.mtlsamplers[SDL_METAL_SAMPLER_LINEAR_CLAMP];
|
|
||||||
break;
|
|
||||||
case SDL_TEXTURE_ADDRESS_WRAP:
|
|
||||||
mtlsampler = data.mtlsamplers[SDL_METAL_SAMPLER_LINEAR_WRAP];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return SDL_SetError("Unknown texture address mode: %d", cmd->data.draw.texture_address_mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[data.mtlcmdencoder setFragmentSamplerState:mtlsampler atIndex:0];
|
|
||||||
|
|
||||||
[data.mtlcmdencoder setFragmentTexture:texturedata.mtltexture atIndex:0];
|
[data.mtlcmdencoder setFragmentTexture:texturedata.mtltexture atIndex:0];
|
||||||
#ifdef SDL_HAVE_YUV
|
#ifdef SDL_HAVE_YUV
|
||||||
if (texturedata.yuv || texturedata.nv12) {
|
if (texturedata.yuv || texturedata.nv12) {
|
||||||
|
@ -1517,6 +1536,20 @@ static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, c
|
||||||
#endif
|
#endif
|
||||||
statecache->texture = texture;
|
statecache->texture = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cmd->data.draw.texture_scale_mode != statecache->texture_scale_mode ||
|
||||||
|
cmd->data.draw.texture_address_mode_u != statecache->texture_address_mode_u ||
|
||||||
|
cmd->data.draw.texture_address_mode_v != statecache->texture_address_mode_v) {
|
||||||
|
id<MTLSamplerState> mtlsampler = GetSampler(data, cmd->data.draw.texture_scale_mode, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
|
||||||
|
if (mtlsampler == nil) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
[data.mtlcmdencoder setFragmentSamplerState:mtlsampler atIndex:0];
|
||||||
|
|
||||||
|
statecache->texture_scale_mode = cmd->data.draw.texture_scale_mode;
|
||||||
|
statecache->texture_address_mode_u = cmd->data.draw.texture_address_mode_u;
|
||||||
|
statecache->texture_address_mode_v = cmd->data.draw.texture_address_mode_v;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1537,6 +1570,9 @@ static bool METAL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd
|
||||||
statecache.vertex_buffer = nil;
|
statecache.vertex_buffer = nil;
|
||||||
statecache.constants_offset = CONSTANTS_OFFSET_INVALID;
|
statecache.constants_offset = CONSTANTS_OFFSET_INVALID;
|
||||||
statecache.texture = NULL;
|
statecache.texture = NULL;
|
||||||
|
statecache.texture_scale_mode = SDL_SCALEMODE_INVALID;
|
||||||
|
statecache.texture_address_mode_u = SDL_TEXTURE_ADDRESS_INVALID;
|
||||||
|
statecache.texture_address_mode_v = SDL_TEXTURE_ADDRESS_INVALID;
|
||||||
statecache.shader_constants_dirty = true;
|
statecache.shader_constants_dirty = true;
|
||||||
statecache.cliprect_dirty = true;
|
statecache.cliprect_dirty = true;
|
||||||
statecache.viewport_dirty = true;
|
statecache.viewport_dirty = true;
|
||||||
|
@ -1897,7 +1933,6 @@ static bool METAL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL
|
||||||
int maxtexsize, quadcount = UINT16_MAX / 4;
|
int maxtexsize, quadcount = UINT16_MAX / 4;
|
||||||
UInt16 *indexdata;
|
UInt16 *indexdata;
|
||||||
size_t indicessize = sizeof(UInt16) * quadcount * 6;
|
size_t indicessize = sizeof(UInt16) * quadcount * 6;
|
||||||
MTLSamplerDescriptor *samplerdesc;
|
|
||||||
id<MTLCommandQueue> mtlcmdqueue;
|
id<MTLCommandQueue> mtlcmdqueue;
|
||||||
id<MTLLibrary> mtllibrary;
|
id<MTLLibrary> mtllibrary;
|
||||||
id<MTLBuffer> mtlbufconstantstaging, mtlbufquadindicesstaging, mtlbufconstants, mtlbufquadindices;
|
id<MTLBuffer> mtlbufconstantstaging, mtlbufquadindicesstaging, mtlbufconstants, mtlbufquadindices;
|
||||||
|
@ -2057,27 +2092,7 @@ static bool METAL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL
|
||||||
data.allpipelines = NULL;
|
data.allpipelines = NULL;
|
||||||
ChooseShaderPipelines(data, MTLPixelFormatBGRA8Unorm);
|
ChooseShaderPipelines(data, MTLPixelFormatBGRA8Unorm);
|
||||||
|
|
||||||
static struct
|
data.mtlsamplers = [[NSMutableDictionary<NSNumber *, id<MTLSamplerState>> alloc] init];
|
||||||
{
|
|
||||||
MTLSamplerMinMagFilter filter;
|
|
||||||
MTLSamplerAddressMode address;
|
|
||||||
} samplerParams[] = {
|
|
||||||
{ MTLSamplerMinMagFilterNearest, MTLSamplerAddressModeClampToEdge },
|
|
||||||
{ MTLSamplerMinMagFilterNearest, MTLSamplerAddressModeRepeat },
|
|
||||||
{ MTLSamplerMinMagFilterLinear, MTLSamplerAddressModeClampToEdge },
|
|
||||||
{ MTLSamplerMinMagFilterLinear, MTLSamplerAddressModeRepeat },
|
|
||||||
};
|
|
||||||
SDL_COMPILE_TIME_ASSERT(samplerParams_SIZE, SDL_arraysize(samplerParams) == SDL_NUM_METAL_SAMPLERS);
|
|
||||||
|
|
||||||
data.mtlsamplers = [[NSMutableArray<id<MTLSamplerState>> alloc] init];
|
|
||||||
samplerdesc = [[MTLSamplerDescriptor alloc] init];
|
|
||||||
for (int i = 0; i < SDL_arraysize(samplerParams); ++i) {
|
|
||||||
samplerdesc.minFilter = samplerParams[i].filter;
|
|
||||||
samplerdesc.magFilter = samplerParams[i].filter;
|
|
||||||
samplerdesc.sAddressMode = samplerParams[i].address;
|
|
||||||
samplerdesc.tAddressMode = samplerParams[i].address;
|
|
||||||
[data.mtlsamplers addObject:[data.mtldevice newSamplerStateWithDescriptor:samplerdesc]];
|
|
||||||
}
|
|
||||||
|
|
||||||
mtlbufconstantstaging = [data.mtldevice newBufferWithLength:CONSTANTS_LENGTH options:MTLResourceStorageModeShared];
|
mtlbufconstantstaging = [data.mtldevice newBufferWithLength:CONSTANTS_LENGTH options:MTLResourceStorageModeShared];
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,8 @@ typedef struct
|
||||||
bool vtexture_external;
|
bool vtexture_external;
|
||||||
#endif
|
#endif
|
||||||
SDL_ScaleMode texture_scale_mode;
|
SDL_ScaleMode texture_scale_mode;
|
||||||
SDL_TextureAddressMode texture_address_mode;
|
SDL_TextureAddressMode texture_address_mode_u;
|
||||||
|
SDL_TextureAddressMode texture_address_mode_v;
|
||||||
GL_FBOList *fbo;
|
GL_FBOList *fbo;
|
||||||
} GL_TextureData;
|
} GL_TextureData;
|
||||||
|
|
||||||
|
@ -538,7 +539,8 @@ static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P
|
||||||
data->format = format;
|
data->format = format;
|
||||||
data->formattype = type;
|
data->formattype = type;
|
||||||
data->texture_scale_mode = SDL_SCALEMODE_INVALID;
|
data->texture_scale_mode = SDL_SCALEMODE_INVALID;
|
||||||
data->texture_address_mode = SDL_TEXTURE_ADDRESS_INVALID;
|
data->texture_address_mode_u = SDL_TEXTURE_ADDRESS_INVALID;
|
||||||
|
data->texture_address_mode_v = SDL_TEXTURE_ADDRESS_INVALID;
|
||||||
renderdata->glEnable(textype);
|
renderdata->glEnable(textype);
|
||||||
renderdata->glBindTexture(textype, data->texture);
|
renderdata->glBindTexture(textype, data->texture);
|
||||||
#ifdef SDL_PLATFORM_MACOS
|
#ifdef SDL_PLATFORM_MACOS
|
||||||
|
@ -1099,21 +1101,23 @@ static bool SetTextureScaleMode(GL_RenderData *data, GLenum textype, SDL_ScaleMo
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool SetTextureAddressMode(GL_RenderData *data, GLenum textype, SDL_TextureAddressMode addressMode)
|
static GLint TranslateAddressMode(SDL_TextureAddressMode addressMode)
|
||||||
{
|
{
|
||||||
switch (addressMode) {
|
switch (addressMode) {
|
||||||
case SDL_TEXTURE_ADDRESS_CLAMP:
|
case SDL_TEXTURE_ADDRESS_CLAMP:
|
||||||
data->glTexParameteri(textype, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
return GL_CLAMP_TO_EDGE;
|
||||||
data->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
break;
|
|
||||||
case SDL_TEXTURE_ADDRESS_WRAP:
|
case SDL_TEXTURE_ADDRESS_WRAP:
|
||||||
data->glTexParameteri(textype, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
return GL_REPEAT;
|
||||||
data->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return SDL_SetError("Unknown texture address mode: %d", addressMode);
|
SDL_assert(!"Unknown texture address mode");
|
||||||
|
return GL_CLAMP_TO_EDGE;
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
static void SetTextureAddressMode(GL_RenderData *data, GLenum textype, SDL_TextureAddressMode addressModeU, SDL_TextureAddressMode addressModeV)
|
||||||
|
{
|
||||||
|
data->glTexParameteri(textype, GL_TEXTURE_WRAP_S, TranslateAddressMode(addressModeU));
|
||||||
|
data->glTexParameteri(textype, GL_TEXTURE_WRAP_T, TranslateAddressMode(addressModeV));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
|
static bool SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
|
||||||
|
@ -1192,34 +1196,28 @@ static bool SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
|
||||||
texturedata->texture_scale_mode = cmd->data.draw.texture_scale_mode;
|
texturedata->texture_scale_mode = cmd->data.draw.texture_scale_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd->data.draw.texture_address_mode != texturedata->texture_address_mode) {
|
if (cmd->data.draw.texture_address_mode_u != texturedata->texture_address_mode_u ||
|
||||||
|
cmd->data.draw.texture_address_mode_v != texturedata->texture_address_mode_v) {
|
||||||
#ifdef SDL_HAVE_YUV
|
#ifdef SDL_HAVE_YUV
|
||||||
if (texturedata->yuv) {
|
if (texturedata->yuv) {
|
||||||
data->glActiveTextureARB(GL_TEXTURE2);
|
data->glActiveTextureARB(GL_TEXTURE2);
|
||||||
if (!SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode)) {
|
SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->glActiveTextureARB(GL_TEXTURE1);
|
data->glActiveTextureARB(GL_TEXTURE1);
|
||||||
if (!SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode)) {
|
SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->glActiveTextureARB(GL_TEXTURE0_ARB);
|
data->glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||||
} else if (texturedata->nv12) {
|
} else if (texturedata->nv12) {
|
||||||
data->glActiveTextureARB(GL_TEXTURE1);
|
data->glActiveTextureARB(GL_TEXTURE1);
|
||||||
if (!SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode)) {
|
SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->glActiveTextureARB(GL_TEXTURE0);
|
data->glActiveTextureARB(GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode)) {
|
SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
texturedata->texture_address_mode = cmd->data.draw.texture_address_mode;
|
texturedata->texture_address_mode_u = cmd->data.draw.texture_address_mode_u;
|
||||||
|
texturedata->texture_address_mode_v = cmd->data.draw.texture_address_mode_v;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1406,7 +1404,8 @@ static bool GL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||||
SDL_Texture *thistexture = cmd->data.draw.texture;
|
SDL_Texture *thistexture = cmd->data.draw.texture;
|
||||||
SDL_BlendMode thisblend = cmd->data.draw.blend;
|
SDL_BlendMode thisblend = cmd->data.draw.blend;
|
||||||
SDL_ScaleMode thisscalemode = cmd->data.draw.texture_scale_mode;
|
SDL_ScaleMode thisscalemode = cmd->data.draw.texture_scale_mode;
|
||||||
SDL_TextureAddressMode thisaddressmode = cmd->data.draw.texture_address_mode;
|
SDL_TextureAddressMode thisaddressmode_u = cmd->data.draw.texture_address_mode_u;
|
||||||
|
SDL_TextureAddressMode thisaddressmode_v = cmd->data.draw.texture_address_mode_v;
|
||||||
const SDL_RenderCommandType thiscmdtype = cmd->command;
|
const SDL_RenderCommandType thiscmdtype = cmd->command;
|
||||||
SDL_RenderCommand *finalcmd = cmd;
|
SDL_RenderCommand *finalcmd = cmd;
|
||||||
SDL_RenderCommand *nextcmd = cmd->next;
|
SDL_RenderCommand *nextcmd = cmd->next;
|
||||||
|
@ -1418,7 +1417,8 @@ static bool GL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||||
break; // can't go any further on this draw call, different render command up next.
|
break; // can't go any further on this draw call, different render command up next.
|
||||||
} else if (nextcmd->data.draw.texture != thistexture ||
|
} else if (nextcmd->data.draw.texture != thistexture ||
|
||||||
nextcmd->data.draw.texture_scale_mode != thisscalemode ||
|
nextcmd->data.draw.texture_scale_mode != thisscalemode ||
|
||||||
nextcmd->data.draw.texture_address_mode != thisaddressmode ||
|
nextcmd->data.draw.texture_address_mode_u != thisaddressmode_u ||
|
||||||
|
nextcmd->data.draw.texture_address_mode_v != thisaddressmode_v ||
|
||||||
nextcmd->data.draw.blend != thisblend) {
|
nextcmd->data.draw.blend != thisblend) {
|
||||||
break; // can't go any further on this draw call, different texture/blendmode copy up next.
|
break; // can't go any further on this draw call, different texture/blendmode copy up next.
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -78,7 +78,8 @@ typedef struct GLES2_TextureData
|
||||||
#endif
|
#endif
|
||||||
GLfloat texel_size[4];
|
GLfloat texel_size[4];
|
||||||
SDL_ScaleMode texture_scale_mode;
|
SDL_ScaleMode texture_scale_mode;
|
||||||
SDL_TextureAddressMode texture_address_mode;
|
SDL_TextureAddressMode texture_address_mode_u;
|
||||||
|
SDL_TextureAddressMode texture_address_mode_v;
|
||||||
GLES2_FBOList *fbo;
|
GLES2_FBOList *fbo;
|
||||||
} GLES2_TextureData;
|
} GLES2_TextureData;
|
||||||
|
|
||||||
|
@ -1092,21 +1093,23 @@ static bool SetTextureScaleMode(GLES2_RenderData *data, GLenum textype, SDL_Scal
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool SetTextureAddressMode(GLES2_RenderData *data, GLenum textype, SDL_TextureAddressMode addressMode)
|
static GLint TranslateAddressMode(SDL_TextureAddressMode addressMode)
|
||||||
{
|
{
|
||||||
switch (addressMode) {
|
switch (addressMode) {
|
||||||
case SDL_TEXTURE_ADDRESS_CLAMP:
|
case SDL_TEXTURE_ADDRESS_CLAMP:
|
||||||
data->glTexParameteri(textype, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
return GL_CLAMP_TO_EDGE;
|
||||||
data->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
break;
|
|
||||||
case SDL_TEXTURE_ADDRESS_WRAP:
|
case SDL_TEXTURE_ADDRESS_WRAP:
|
||||||
data->glTexParameteri(textype, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
return GL_REPEAT;
|
||||||
data->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return SDL_SetError("Unknown texture address mode: %d", addressMode);
|
SDL_assert(!"Unknown texture address mode");
|
||||||
|
return GL_CLAMP_TO_EDGE;
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
static void SetTextureAddressMode(GLES2_RenderData *data, GLenum textype, SDL_TextureAddressMode addressModeU, SDL_TextureAddressMode addressModeV)
|
||||||
|
{
|
||||||
|
data->glTexParameteri(textype, GL_TEXTURE_WRAP_S, TranslateAddressMode(addressModeU));
|
||||||
|
data->glTexParameteri(textype, GL_TEXTURE_WRAP_T, TranslateAddressMode(addressModeV));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertices)
|
static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertices)
|
||||||
|
@ -1287,34 +1290,28 @@ static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, v
|
||||||
tdata->texture_scale_mode = cmd->data.draw.texture_scale_mode;
|
tdata->texture_scale_mode = cmd->data.draw.texture_scale_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd->data.draw.texture_address_mode != tdata->texture_address_mode) {
|
if (cmd->data.draw.texture_address_mode_u != tdata->texture_address_mode_u ||
|
||||||
|
cmd->data.draw.texture_address_mode_v != tdata->texture_address_mode_v) {
|
||||||
#ifdef SDL_HAVE_YUV
|
#ifdef SDL_HAVE_YUV
|
||||||
if (tdata->yuv) {
|
if (tdata->yuv) {
|
||||||
data->glActiveTexture(GL_TEXTURE2);
|
data->glActiveTexture(GL_TEXTURE2);
|
||||||
if (!SetTextureAddressMode(data, tdata->texture_type, cmd->data.draw.texture_address_mode)) {
|
SetTextureAddressMode(data, tdata->texture_type, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->glActiveTexture(GL_TEXTURE1);
|
data->glActiveTexture(GL_TEXTURE1);
|
||||||
if (!SetTextureAddressMode(data, tdata->texture_type, cmd->data.draw.texture_address_mode)) {
|
SetTextureAddressMode(data, tdata->texture_type, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->glActiveTexture(GL_TEXTURE0);
|
data->glActiveTexture(GL_TEXTURE0);
|
||||||
} else if (tdata->nv12) {
|
} else if (tdata->nv12) {
|
||||||
data->glActiveTexture(GL_TEXTURE1);
|
data->glActiveTexture(GL_TEXTURE1);
|
||||||
if (!SetTextureAddressMode(data, tdata->texture_type, cmd->data.draw.texture_address_mode)) {
|
SetTextureAddressMode(data, tdata->texture_type, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->glActiveTexture(GL_TEXTURE0);
|
data->glActiveTexture(GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!SetTextureAddressMode(data, tdata->texture_type, cmd->data.draw.texture_address_mode)) {
|
SetTextureAddressMode(data, tdata->texture_type, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
tdata->texture_address_mode = cmd->data.draw.texture_address_mode;
|
tdata->texture_address_mode_u = cmd->data.draw.texture_address_mode_u;
|
||||||
|
tdata->texture_address_mode_v = cmd->data.draw.texture_address_mode_v;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1493,7 +1490,8 @@ static bool GLES2_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd
|
||||||
SDL_Texture *thistexture = cmd->data.draw.texture;
|
SDL_Texture *thistexture = cmd->data.draw.texture;
|
||||||
SDL_BlendMode thisblend = cmd->data.draw.blend;
|
SDL_BlendMode thisblend = cmd->data.draw.blend;
|
||||||
SDL_ScaleMode thisscalemode = cmd->data.draw.texture_scale_mode;
|
SDL_ScaleMode thisscalemode = cmd->data.draw.texture_scale_mode;
|
||||||
SDL_TextureAddressMode thisaddressmode = cmd->data.draw.texture_address_mode;
|
SDL_TextureAddressMode thisaddressmode_u = cmd->data.draw.texture_address_mode_u;
|
||||||
|
SDL_TextureAddressMode thisaddressmode_v = cmd->data.draw.texture_address_mode_v;
|
||||||
const SDL_RenderCommandType thiscmdtype = cmd->command;
|
const SDL_RenderCommandType thiscmdtype = cmd->command;
|
||||||
SDL_RenderCommand *finalcmd = cmd;
|
SDL_RenderCommand *finalcmd = cmd;
|
||||||
SDL_RenderCommand *nextcmd = cmd->next;
|
SDL_RenderCommand *nextcmd = cmd->next;
|
||||||
|
@ -1505,7 +1503,8 @@ static bool GLES2_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd
|
||||||
break; // can't go any further on this draw call, different render command up next.
|
break; // can't go any further on this draw call, different render command up next.
|
||||||
} else if (nextcmd->data.draw.texture != thistexture ||
|
} else if (nextcmd->data.draw.texture != thistexture ||
|
||||||
nextcmd->data.draw.texture_scale_mode != thisscalemode ||
|
nextcmd->data.draw.texture_scale_mode != thisscalemode ||
|
||||||
nextcmd->data.draw.texture_address_mode != thisaddressmode ||
|
nextcmd->data.draw.texture_address_mode_u != thisaddressmode_u ||
|
||||||
|
nextcmd->data.draw.texture_address_mode_v != thisaddressmode_v ||
|
||||||
nextcmd->data.draw.blend != thisblend) {
|
nextcmd->data.draw.blend != thisblend) {
|
||||||
break; // can't go any further on this draw call, different texture/blendmode copy up next.
|
break; // can't go any further on this draw call, different texture/blendmode copy up next.
|
||||||
} else {
|
} else {
|
||||||
|
@ -1660,7 +1659,8 @@ static bool GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
|
||||||
data->texture_v = 0;
|
data->texture_v = 0;
|
||||||
#endif
|
#endif
|
||||||
data->texture_scale_mode = SDL_SCALEMODE_INVALID;
|
data->texture_scale_mode = SDL_SCALEMODE_INVALID;
|
||||||
data->texture_address_mode = SDL_TEXTURE_ADDRESS_INVALID;
|
data->texture_address_mode_u = SDL_TEXTURE_ADDRESS_INVALID;
|
||||||
|
data->texture_address_mode_v = SDL_TEXTURE_ADDRESS_INVALID;
|
||||||
|
|
||||||
// Allocate a blob for image renderdata
|
// Allocate a blob for image renderdata
|
||||||
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
|
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
|
||||||
|
|
|
@ -76,7 +76,8 @@ typedef struct
|
||||||
int shadeModel;
|
int shadeModel;
|
||||||
SDL_Texture *texture;
|
SDL_Texture *texture;
|
||||||
SDL_ScaleMode texture_scale_mode;
|
SDL_ScaleMode texture_scale_mode;
|
||||||
SDL_TextureAddressMode texture_address_mode;
|
SDL_TextureAddressMode texture_address_mode_u;
|
||||||
|
SDL_TextureAddressMode texture_address_mode_v;
|
||||||
} PSP_BlendState;
|
} PSP_BlendState;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -540,20 +541,6 @@ static bool TextureShouldSwizzle(PSP_TextureData *psp_texture, SDL_Texture *text
|
||||||
return !((texture->access == SDL_TEXTUREACCESS_TARGET) && InVram(psp_texture->data)) && texture->access != SDL_TEXTUREACCESS_STREAMING && (texture->w >= 16 || texture->h >= 16);
|
return !((texture->access == SDL_TEXTUREACCESS_TARGET) && InVram(psp_texture->data)) && texture->access != SDL_TEXTUREACCESS_STREAMING && (texture->w >= 16 || texture->h >= 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetTextureAddressMode(SDL_TextureAddressMode addressMode)
|
|
||||||
{
|
|
||||||
switch (addressMode) {
|
|
||||||
case SDL_TEXTURE_ADDRESS_CLAMP:
|
|
||||||
sceGuTexWrap(GU_CLAMP, GU_CLAMP);
|
|
||||||
break;
|
|
||||||
case SDL_TEXTURE_ADDRESS_WRAP:
|
|
||||||
sceGuTexWrap(GU_REPEAT, GU_REPEAT);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SetTextureScaleMode(SDL_ScaleMode scaleMode)
|
static void SetTextureScaleMode(SDL_ScaleMode scaleMode)
|
||||||
{
|
{
|
||||||
switch (scaleMode) {
|
switch (scaleMode) {
|
||||||
|
@ -569,6 +556,24 @@ static void SetTextureScaleMode(SDL_ScaleMode scaleMode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int TranslateAddressMode(SDL_TextureAddressMode mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case SDL_TEXTURE_ADDRESS_CLAMP:
|
||||||
|
return GU_CLAMP;
|
||||||
|
case SDL_TEXTURE_ADDRESS_WRAP:
|
||||||
|
return GU_REPEAT;
|
||||||
|
default:
|
||||||
|
SDL_assert(!"Unknown texture address mode");
|
||||||
|
return GU_CLAMP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetTextureAddressMode(SDL_TextureAddressMode addressModeU, SDL_TextureAddressMode addressModeV)
|
||||||
|
{
|
||||||
|
sceGuTexWrap(TranslateAddressMode(addressModeU), TranslateAddressMode(addressModeV));
|
||||||
|
}
|
||||||
|
|
||||||
static void TextureActivate(SDL_Texture *texture)
|
static void TextureActivate(SDL_Texture *texture)
|
||||||
{
|
{
|
||||||
PSP_TextureData *psp_texture = (PSP_TextureData *)texture->internal;
|
PSP_TextureData *psp_texture = (PSP_TextureData *)texture->internal;
|
||||||
|
@ -1058,7 +1063,7 @@ static void PSP_SetBlendState(PSP_RenderData *data, PSP_BlendState *state)
|
||||||
|
|
||||||
if (state->texture) {
|
if (state->texture) {
|
||||||
SetTextureScaleMode(state->texture_scale_mode);
|
SetTextureScaleMode(state->texture_scale_mode);
|
||||||
SetTextureAddressMode(state->texture_address_mode);
|
SetTextureAddressMode(state->texture_address_mode_u, state->texture_address_mode_v);
|
||||||
}
|
}
|
||||||
|
|
||||||
*current = *state;
|
*current = *state;
|
||||||
|
@ -1145,7 +1150,8 @@ static bool PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||||
.color = drawstate.color,
|
.color = drawstate.color,
|
||||||
.texture = NULL,
|
.texture = NULL,
|
||||||
.texture_scale_mode = SDL_SCALEMODE_INVALID,
|
.texture_scale_mode = SDL_SCALEMODE_INVALID,
|
||||||
.texture_address_mode = SDL_TEXTURE_ADDRESS_INVALID,
|
.texture_address_mode_u = SDL_TEXTURE_ADDRESS_INVALID,
|
||||||
|
.texture_address_mode_v = SDL_TEXTURE_ADDRESS_INVALID,
|
||||||
.mode = cmd->data.draw.blend,
|
.mode = cmd->data.draw.blend,
|
||||||
.shadeModel = GU_FLAT
|
.shadeModel = GU_FLAT
|
||||||
};
|
};
|
||||||
|
@ -1162,7 +1168,8 @@ static bool PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||||
.color = drawstate.color,
|
.color = drawstate.color,
|
||||||
.texture = NULL,
|
.texture = NULL,
|
||||||
.texture_scale_mode = SDL_SCALEMODE_INVALID,
|
.texture_scale_mode = SDL_SCALEMODE_INVALID,
|
||||||
.texture_address_mode = SDL_TEXTURE_ADDRESS_INVALID,
|
.texture_address_mode_u = SDL_TEXTURE_ADDRESS_INVALID,
|
||||||
|
.texture_address_mode_v = SDL_TEXTURE_ADDRESS_INVALID,
|
||||||
.mode = cmd->data.draw.blend,
|
.mode = cmd->data.draw.blend,
|
||||||
.shadeModel = GU_FLAT
|
.shadeModel = GU_FLAT
|
||||||
};
|
};
|
||||||
|
@ -1179,7 +1186,8 @@ static bool PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||||
.color = drawstate.color,
|
.color = drawstate.color,
|
||||||
.texture = NULL,
|
.texture = NULL,
|
||||||
.texture_scale_mode = SDL_SCALEMODE_INVALID,
|
.texture_scale_mode = SDL_SCALEMODE_INVALID,
|
||||||
.texture_address_mode = SDL_TEXTURE_ADDRESS_INVALID,
|
.texture_address_mode_u = SDL_TEXTURE_ADDRESS_INVALID,
|
||||||
|
.texture_address_mode_v = SDL_TEXTURE_ADDRESS_INVALID,
|
||||||
.mode = cmd->data.draw.blend,
|
.mode = cmd->data.draw.blend,
|
||||||
.shadeModel = GU_FLAT
|
.shadeModel = GU_FLAT
|
||||||
};
|
};
|
||||||
|
@ -1196,7 +1204,8 @@ static bool PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||||
.color = drawstate.color,
|
.color = drawstate.color,
|
||||||
.texture = cmd->data.draw.texture,
|
.texture = cmd->data.draw.texture,
|
||||||
.texture_scale_mode = cmd->data.draw.texture_scale_mode,
|
.texture_scale_mode = cmd->data.draw.texture_scale_mode,
|
||||||
.texture_address_mode = cmd->data.draw.texture_address_mode,
|
.texture_address_mode_u = cmd->data.draw.texture_address_mode_u,
|
||||||
|
.texture_address_mode_v = cmd->data.draw.texture_address_mode_v,
|
||||||
.mode = cmd->data.draw.blend,
|
.mode = cmd->data.draw.blend,
|
||||||
.shadeModel = GU_SMOOTH
|
.shadeModel = GU_SMOOTH
|
||||||
};
|
};
|
||||||
|
@ -1212,7 +1221,8 @@ static bool PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||||
.color = drawstate.color,
|
.color = drawstate.color,
|
||||||
.texture = cmd->data.draw.texture,
|
.texture = cmd->data.draw.texture,
|
||||||
.texture_scale_mode = cmd->data.draw.texture_scale_mode,
|
.texture_scale_mode = cmd->data.draw.texture_scale_mode,
|
||||||
.texture_address_mode = cmd->data.draw.texture_address_mode,
|
.texture_address_mode_u = cmd->data.draw.texture_address_mode_u,
|
||||||
|
.texture_address_mode_v = cmd->data.draw.texture_address_mode_v,
|
||||||
.mode = cmd->data.draw.blend,
|
.mode = cmd->data.draw.blend,
|
||||||
.shadeModel = GU_SMOOTH
|
.shadeModel = GU_SMOOTH
|
||||||
};
|
};
|
||||||
|
@ -1236,7 +1246,8 @@ static bool PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||||
.color = drawstate.color,
|
.color = drawstate.color,
|
||||||
.texture = cmd->data.draw.texture,
|
.texture = cmd->data.draw.texture,
|
||||||
.texture_scale_mode = cmd->data.draw.texture_scale_mode,
|
.texture_scale_mode = cmd->data.draw.texture_scale_mode,
|
||||||
.texture_address_mode = cmd->data.draw.texture_address_mode,
|
.texture_address_mode_u = cmd->data.draw.texture_address_mode_u,
|
||||||
|
.texture_address_mode_v = cmd->data.draw.texture_address_mode_v,
|
||||||
.mode = cmd->data.draw.blend,
|
.mode = cmd->data.draw.blend,
|
||||||
.shadeModel = GU_SMOOTH
|
.shadeModel = GU_SMOOTH
|
||||||
};
|
};
|
||||||
|
|
|
@ -925,7 +925,8 @@ static bool SW_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||||
surface,
|
surface,
|
||||||
&(ptr[0].dst), &(ptr[1].dst), &(ptr[2].dst),
|
&(ptr[0].dst), &(ptr[1].dst), &(ptr[2].dst),
|
||||||
ptr[0].color, ptr[1].color, ptr[2].color,
|
ptr[0].color, ptr[1].color, ptr[2].color,
|
||||||
cmd->data.draw.texture_address_mode);
|
cmd->data.draw.texture_address_mode_u,
|
||||||
|
cmd->data.draw.texture_address_mode_v);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GeometryFillData *ptr = (GeometryFillData *)verts;
|
GeometryFillData *ptr = (GeometryFillData *)verts;
|
||||||
|
|
|
@ -42,7 +42,9 @@ 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,
|
SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2,
|
||||||
int d2d1_y, int d1d2_x, int d0d2_y, int d2d0_x, int d1d0_y, int d0d1_x,
|
int d2d1_y, int d1d2_x, int d0d2_y, int d2d0_x, int d1d0_y, int d0d1_x,
|
||||||
int s2s0_x, int s2s1_x, int s2s0_y, int s2s1_y, int w0_row, int w1_row, int w2_row,
|
int s2s0_x, int s2s1_x, int s2s0_y, int s2s1_y, int w0_row, int w1_row, int w2_row,
|
||||||
SDL_Color c0, SDL_Color c1, SDL_Color c2, bool is_uniform, SDL_TextureAddressMode texture_address_mode);
|
SDL_Color c0, SDL_Color c1, SDL_Color c2, bool is_uniform,
|
||||||
|
SDL_TextureAddressMode texture_address_mode_u,
|
||||||
|
SDL_TextureAddressMode texture_address_mode_v);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
bool SDL_BlitTriangle(SDL_Surface *src, const SDL_Point srcpoints[3], SDL_Surface *dst, const SDL_Point dstpoints[3])
|
bool SDL_BlitTriangle(SDL_Surface *src, const SDL_Point srcpoints[3], SDL_Surface *dst, const SDL_Point dstpoints[3])
|
||||||
|
@ -184,11 +186,13 @@ static void bounding_rect(const SDL_Point *a, const SDL_Point *b, const SDL_Poin
|
||||||
#define TRIANGLE_GET_TEXTCOORD \
|
#define TRIANGLE_GET_TEXTCOORD \
|
||||||
int srcx = (int)(((Sint64)w0 * s2s0_x + (Sint64)w1 * s2s1_x + s2_x_area.x) / area); \
|
int srcx = (int)(((Sint64)w0 * s2s0_x + (Sint64)w1 * s2s1_x + s2_x_area.x) / area); \
|
||||||
int srcy = (int)(((Sint64)w0 * s2s0_y + (Sint64)w1 * s2s1_y + s2_x_area.y) / area); \
|
int srcy = (int)(((Sint64)w0 * s2s0_y + (Sint64)w1 * s2s1_y + s2_x_area.y) / area); \
|
||||||
if (texture_address_mode == SDL_TEXTURE_ADDRESS_WRAP) { \
|
if (texture_address_mode_u == SDL_TEXTURE_ADDRESS_WRAP) { \
|
||||||
srcx %= src_surface->w; \
|
srcx %= src_surface->w; \
|
||||||
if (srcx < 0) { \
|
if (srcx < 0) { \
|
||||||
srcx += (src_surface->w - 1); \
|
srcx += (src_surface->w - 1); \
|
||||||
} \
|
} \
|
||||||
|
} \
|
||||||
|
if (texture_address_mode_v == SDL_TEXTURE_ADDRESS_WRAP) { \
|
||||||
srcy %= src_surface->h; \
|
srcy %= src_surface->h; \
|
||||||
if (srcy < 0) { \
|
if (srcy < 0) { \
|
||||||
srcy += (src_surface->h - 1); \
|
srcy += (src_surface->h - 1); \
|
||||||
|
@ -465,7 +469,8 @@ bool SDL_SW_BlitTriangle(
|
||||||
SDL_Surface *dst,
|
SDL_Surface *dst,
|
||||||
SDL_Point *d0, SDL_Point *d1, SDL_Point *d2,
|
SDL_Point *d0, SDL_Point *d1, SDL_Point *d2,
|
||||||
SDL_Color c0, SDL_Color c1, SDL_Color c2,
|
SDL_Color c0, SDL_Color c1, SDL_Color c2,
|
||||||
SDL_TextureAddressMode texture_address_mode)
|
SDL_TextureAddressMode texture_address_mode_u,
|
||||||
|
SDL_TextureAddressMode texture_address_mode_v)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
SDL_Surface *src_surface = src;
|
SDL_Surface *src_surface = src;
|
||||||
|
@ -539,32 +544,36 @@ bool SDL_SW_BlitTriangle(
|
||||||
SDL_GetSurfaceBlendMode(src, &blend);
|
SDL_GetSurfaceBlendMode(src, &blend);
|
||||||
|
|
||||||
// TRIANGLE_GET_TEXTCOORD interpolates up to the max values included, so reduce by 1
|
// TRIANGLE_GET_TEXTCOORD interpolates up to the max values included, so reduce by 1
|
||||||
if (texture_address_mode == SDL_TEXTURE_ADDRESS_CLAMP) {
|
if (texture_address_mode_u == SDL_TEXTURE_ADDRESS_CLAMP ||
|
||||||
|
texture_address_mode_v == SDL_TEXTURE_ADDRESS_CLAMP) {
|
||||||
SDL_Rect srcrect;
|
SDL_Rect srcrect;
|
||||||
int maxx, maxy;
|
|
||||||
bounding_rect(s0, s1, s2, &srcrect);
|
bounding_rect(s0, s1, s2, &srcrect);
|
||||||
maxx = srcrect.x + srcrect.w;
|
if (texture_address_mode_u == SDL_TEXTURE_ADDRESS_CLAMP) {
|
||||||
maxy = srcrect.y + srcrect.h;
|
int maxx = srcrect.x + srcrect.w;
|
||||||
if (srcrect.w > 0) {
|
if (srcrect.w > 0) {
|
||||||
if (s0->x == maxx) {
|
if (s0->x == maxx) {
|
||||||
s0->x--;
|
s0->x--;
|
||||||
}
|
}
|
||||||
if (s1->x == maxx) {
|
if (s1->x == maxx) {
|
||||||
s1->x--;
|
s1->x--;
|
||||||
}
|
}
|
||||||
if (s2->x == maxx) {
|
if (s2->x == maxx) {
|
||||||
s2->x--;
|
s2->x--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (srcrect.h > 0) {
|
if (texture_address_mode_v == SDL_TEXTURE_ADDRESS_CLAMP) {
|
||||||
if (s0->y == maxy) {
|
int maxy = srcrect.y + srcrect.h;
|
||||||
s0->y--;
|
if (srcrect.h > 0) {
|
||||||
}
|
if (s0->y == maxy) {
|
||||||
if (s1->y == maxy) {
|
s0->y--;
|
||||||
s1->y--;
|
}
|
||||||
}
|
if (s1->y == maxy) {
|
||||||
if (s2->y == maxy) {
|
s1->y--;
|
||||||
s2->y--;
|
}
|
||||||
|
if (s2->y == maxy) {
|
||||||
|
s2->y--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -716,7 +725,7 @@ bool SDL_SW_BlitTriangle(
|
||||||
SDL_BlitTriangle_Slow(&tmp_info, s2_x_area, dstrect, (int)area, bias_w0, bias_w1, bias_w2,
|
SDL_BlitTriangle_Slow(&tmp_info, s2_x_area, dstrect, (int)area, bias_w0, bias_w1, bias_w2,
|
||||||
d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x,
|
d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x,
|
||||||
s2s0_x, s2s1_x, s2s0_y, s2s1_y, (int)w0_row, (int)w1_row, (int)w2_row,
|
s2s0_x, s2s1_x, s2s0_y, s2s1_y, (int)w0_row, (int)w1_row, (int)w2_row,
|
||||||
c0, c1, c2, is_uniform, texture_address_mode);
|
c0, c1, c2, is_uniform, texture_address_mode_u, texture_address_mode_v);
|
||||||
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -788,7 +797,9 @@ 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,
|
SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2,
|
||||||
int d2d1_y, int d1d2_x, int d0d2_y, int d2d0_x, int d1d0_y, int d0d1_x,
|
int d2d1_y, int d1d2_x, int d0d2_y, int d2d0_x, int d1d0_y, int d0d1_x,
|
||||||
int s2s0_x, int s2s1_x, int s2s0_y, int s2s1_y, int w0_row, int w1_row, int w2_row,
|
int s2s0_x, int s2s1_x, int s2s0_y, int s2s1_y, int w0_row, int w1_row, int w2_row,
|
||||||
SDL_Color c0, SDL_Color c1, SDL_Color c2, bool is_uniform, SDL_TextureAddressMode texture_address_mode)
|
SDL_Color c0, SDL_Color c1, SDL_Color c2, bool is_uniform,
|
||||||
|
SDL_TextureAddressMode texture_address_mode_u,
|
||||||
|
SDL_TextureAddressMode texture_address_mode_v)
|
||||||
{
|
{
|
||||||
SDL_Surface *src_surface = info->src_surface;
|
SDL_Surface *src_surface = info->src_surface;
|
||||||
const int flags = info->flags;
|
const int flags = info->flags;
|
||||||
|
|
|
@ -24,8 +24,6 @@
|
||||||
|
|
||||||
#include "SDL_internal.h"
|
#include "SDL_internal.h"
|
||||||
|
|
||||||
#include "../SDL_sysrender.h" // For SDL_TextureAddressMode
|
|
||||||
|
|
||||||
extern bool SDL_SW_FillTriangle(SDL_Surface *dst,
|
extern bool SDL_SW_FillTriangle(SDL_Surface *dst,
|
||||||
SDL_Point *d0, SDL_Point *d1, SDL_Point *d2,
|
SDL_Point *d0, SDL_Point *d1, SDL_Point *d2,
|
||||||
SDL_BlendMode blend, SDL_Color c0, SDL_Color c1, SDL_Color c2);
|
SDL_BlendMode blend, SDL_Color c0, SDL_Color c1, SDL_Color c2);
|
||||||
|
@ -35,7 +33,8 @@ extern bool SDL_SW_BlitTriangle(SDL_Surface *src,
|
||||||
SDL_Surface *dst,
|
SDL_Surface *dst,
|
||||||
SDL_Point *d0, SDL_Point *d1, SDL_Point *d2,
|
SDL_Point *d0, SDL_Point *d1, SDL_Point *d2,
|
||||||
SDL_Color c0, SDL_Color c1, SDL_Color c2,
|
SDL_Color c0, SDL_Color c1, SDL_Color c2,
|
||||||
SDL_TextureAddressMode texture_address_mode);
|
SDL_TextureAddressMode texture_address_mode_u,
|
||||||
|
SDL_TextureAddressMode texture_address_mode_v);
|
||||||
|
|
||||||
extern void trianglepoint_2_fixedpoint(SDL_Point *a);
|
extern void trianglepoint_2_fixedpoint(SDL_Point *a);
|
||||||
|
|
||||||
|
|
|
@ -293,7 +293,8 @@ static bool VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||||
}
|
}
|
||||||
|
|
||||||
vita_texture->scale_mode = SDL_SCALEMODE_INVALID;
|
vita_texture->scale_mode = SDL_SCALEMODE_INVALID;
|
||||||
vita_texture->address_mode = SDL_TEXTURE_ADDRESS_INVALID;
|
vita_texture->address_mode_u = SDL_TEXTURE_ADDRESS_INVALID;
|
||||||
|
vita_texture->address_mode_v = SDL_TEXTURE_ADDRESS_INVALID;
|
||||||
|
|
||||||
texture->internal = vita_texture;
|
texture->internal = vita_texture;
|
||||||
|
|
||||||
|
@ -806,6 +807,19 @@ static bool VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SceGxmTextureAddrMode TranslateAddressMode(SDL_TextureAddressMode mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case SDL_TEXTURE_ADDRESS_CLAMP:
|
||||||
|
return SCE_GXM_TEXTURE_ADDR_CLAMP;
|
||||||
|
case SDL_TEXTURE_ADDRESS_WRAP:
|
||||||
|
return SCE_GXM_TEXTURE_ADDR_REPEAT;
|
||||||
|
default:
|
||||||
|
SDL_assert(!"Unknown texture address mode");
|
||||||
|
return SCE_GXM_TEXTURE_ADDR_CLAMP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
|
static bool SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
|
||||||
{
|
{
|
||||||
SDL_Texture *texture = cmd->data.draw.texture;
|
SDL_Texture *texture = cmd->data.draw.texture;
|
||||||
|
@ -906,18 +920,13 @@ static bool SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd
|
||||||
vita_texture->scale_mode = cmd->data.draw.texture_scale_mode;
|
vita_texture->scale_mode = cmd->data.draw.texture_scale_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd->data.draw.texture_address_mode != vita_texture->address_mode) {
|
if (cmd->data.draw.texture_address_mode_u != vita_texture->address_mode_u ||
|
||||||
switch (cmd->data.draw.texture_address_mode) {
|
cmd->data.draw.texture_address_mode_v != vita_texture->address_mode_v) {
|
||||||
case SDL_TEXTURE_ADDRESS_CLAMP:
|
SceGxmTextureAddrMode mode_u = TranslateAddressMode(cmd->data.draw.texture_address_mode_u);
|
||||||
gxm_texture_set_address_mode(vita_texture->tex, SCE_GXM_TEXTURE_ADDR_CLAMP, SCE_GXM_TEXTURE_ADDR_CLAMP);
|
SceGxmTextureAddrMode mode_v = TranslateAddressMode(cmd->data.draw.texture_address_mode_v);
|
||||||
break;
|
gxm_texture_set_address_mode(vita_texture->tex, mode_u, mode_v);
|
||||||
case SDL_TEXTURE_ADDRESS_WRAP:
|
vita_texture->address_mode_u = cmd->data.draw.texture_address_mode_u;
|
||||||
gxm_texture_set_address_mode(vita_texture->tex, SCE_GXM_TEXTURE_ADDR_REPEAT, SCE_GXM_TEXTURE_ADDR_REPEAT);
|
vita_texture->address_mode_v = cmd->data.draw.texture_address_mode_v;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
vita_texture->address_mode = cmd->data.draw.texture_address_mode;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,8 @@ typedef struct
|
||||||
bool yuv;
|
bool yuv;
|
||||||
bool nv12;
|
bool nv12;
|
||||||
SDL_ScaleMode scale_mode;
|
SDL_ScaleMode scale_mode;
|
||||||
SDL_TextureAddressMode address_mode;
|
SDL_TextureAddressMode address_mode_u;
|
||||||
|
SDL_TextureAddressMode address_mode_v;
|
||||||
} VITA_GXM_TextureData;
|
} VITA_GXM_TextureData;
|
||||||
|
|
||||||
#endif // SDL_RENDER_VITA_GXM_TYPES_H
|
#endif // SDL_RENDER_VITA_GXM_TYPES_H
|
||||||
|
|
|
@ -169,16 +169,6 @@ typedef enum {
|
||||||
VULKAN_RENDERPASS_COUNT
|
VULKAN_RENDERPASS_COUNT
|
||||||
} VULKAN_RenderPass;
|
} VULKAN_RenderPass;
|
||||||
|
|
||||||
// Sampler types
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
VULKAN_SAMPLER_NEAREST_CLAMP,
|
|
||||||
VULKAN_SAMPLER_NEAREST_WRAP,
|
|
||||||
VULKAN_SAMPLER_LINEAR_CLAMP,
|
|
||||||
VULKAN_SAMPLER_LINEAR_WRAP,
|
|
||||||
VULKAN_SAMPLER_COUNT
|
|
||||||
} VULKAN_Sampler;
|
|
||||||
|
|
||||||
// Vertex shader, common values
|
// Vertex shader, common values
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -196,15 +186,6 @@ static const float INPUTTYPE_SRGB = 1;
|
||||||
static const float INPUTTYPE_SCRGB = 2;
|
static const float INPUTTYPE_SCRGB = 2;
|
||||||
static const float INPUTTYPE_HDR10 = 3;
|
static const float INPUTTYPE_HDR10 = 3;
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
SAMPLER_POINT_CLAMP,
|
|
||||||
SAMPLER_POINT_WRAP,
|
|
||||||
SAMPLER_LINEAR_CLAMP,
|
|
||||||
SAMPLER_LINEAR_WRAP,
|
|
||||||
NUM_SAMPLERS
|
|
||||||
} Sampler;
|
|
||||||
|
|
||||||
// Pixel shader constants, common values
|
// Pixel shader constants, common values
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -347,7 +328,7 @@ typedef struct
|
||||||
uint32_t currentConstantBufferIndex;
|
uint32_t currentConstantBufferIndex;
|
||||||
int32_t currentConstantBufferOffset;
|
int32_t currentConstantBufferOffset;
|
||||||
|
|
||||||
VkSampler samplers[VULKAN_SAMPLER_COUNT];
|
VkSampler samplers[RENDER_SAMPLER_COUNT];
|
||||||
VkDescriptorPool **descriptorPools;
|
VkDescriptorPool **descriptorPools;
|
||||||
uint32_t *numDescriptorPools;
|
uint32_t *numDescriptorPools;
|
||||||
uint32_t currentDescriptorPoolIndex;
|
uint32_t currentDescriptorPoolIndex;
|
||||||
|
@ -1950,42 +1931,6 @@ static VkResult VULKAN_CreateDeviceResources(SDL_Renderer *renderer, SDL_Propert
|
||||||
VULKAN_CreateVertexBuffer(rendererData, i, SDL_VULKAN_VERTEX_BUFFER_DEFAULT_SIZE);
|
VULKAN_CreateVertexBuffer(rendererData, i, SDL_VULKAN_VERTEX_BUFFER_DEFAULT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create samplers
|
|
||||||
{
|
|
||||||
static struct
|
|
||||||
{
|
|
||||||
VkFilter filter;
|
|
||||||
VkSamplerAddressMode address;
|
|
||||||
} samplerParams[] = {
|
|
||||||
{ VK_FILTER_NEAREST, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE },
|
|
||||||
{ VK_FILTER_NEAREST, VK_SAMPLER_ADDRESS_MODE_REPEAT },
|
|
||||||
{ VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE },
|
|
||||||
{ VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT },
|
|
||||||
};
|
|
||||||
SDL_COMPILE_TIME_ASSERT(samplerParams_SIZE, SDL_arraysize(samplerParams) == VULKAN_SAMPLER_COUNT);
|
|
||||||
VkSamplerCreateInfo samplerCreateInfo = { 0 };
|
|
||||||
samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
|
||||||
samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
|
||||||
samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
|
||||||
samplerCreateInfo.mipLodBias = 0.0f;
|
|
||||||
samplerCreateInfo.anisotropyEnable = VK_FALSE;
|
|
||||||
samplerCreateInfo.maxAnisotropy = 1.0f;
|
|
||||||
samplerCreateInfo.minLod = 0.0f;
|
|
||||||
samplerCreateInfo.maxLod = 1000.0f;
|
|
||||||
for (int i = 0; i < SDL_arraysize(samplerParams); ++i) {
|
|
||||||
samplerCreateInfo.magFilter = samplerParams[i].filter;
|
|
||||||
samplerCreateInfo.minFilter = samplerParams[i].filter;
|
|
||||||
samplerCreateInfo.addressModeU = samplerParams[i].address;
|
|
||||||
samplerCreateInfo.addressModeV = samplerParams[i].address;
|
|
||||||
result = vkCreateSampler(rendererData->device, &samplerCreateInfo, NULL, &rendererData->samplers[i]);
|
|
||||||
if (result != VK_SUCCESS) {
|
|
||||||
VULKAN_DestroyAll(renderer);
|
|
||||||
SET_ERROR_CODE("vkCreateSampler()", result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_PropertiesID props = SDL_GetRendererProperties(renderer);
|
SDL_PropertiesID props = SDL_GetRendererProperties(renderer);
|
||||||
SDL_SetPointerProperty(props, SDL_PROP_RENDERER_VULKAN_INSTANCE_POINTER, rendererData->instance);
|
SDL_SetPointerProperty(props, SDL_PROP_RENDERER_VULKAN_INSTANCE_POINTER, rendererData->instance);
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_RENDERER_VULKAN_SURFACE_NUMBER, (Sint64)rendererData->surface);
|
SDL_SetNumberProperty(props, SDL_PROP_RENDERER_VULKAN_SURFACE_NUMBER, (Sint64)rendererData->surface);
|
||||||
|
@ -3762,6 +3707,42 @@ static bool VULKAN_SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VkSampler VULKAN_GetSampler(VULKAN_RenderData *data, SDL_ScaleMode scale_mode, SDL_TextureAddressMode address_u, SDL_TextureAddressMode address_v)
|
||||||
|
{
|
||||||
|
Uint32 key = RENDER_SAMPLER_HASHKEY(scale_mode, address_u, address_v);
|
||||||
|
SDL_assert(key < SDL_arraysize(data->samplers));
|
||||||
|
if (!data->samplers[key]) {
|
||||||
|
VkSamplerCreateInfo samplerCreateInfo = { 0 };
|
||||||
|
samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||||
|
samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||||
|
samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
|
samplerCreateInfo.mipLodBias = 0.0f;
|
||||||
|
samplerCreateInfo.anisotropyEnable = VK_FALSE;
|
||||||
|
samplerCreateInfo.maxAnisotropy = 1.0f;
|
||||||
|
samplerCreateInfo.minLod = 0.0f;
|
||||||
|
samplerCreateInfo.maxLod = 1000.0f;
|
||||||
|
switch (scale_mode) {
|
||||||
|
case SDL_SCALEMODE_NEAREST:
|
||||||
|
samplerCreateInfo.magFilter = VK_FILTER_NEAREST;
|
||||||
|
samplerCreateInfo.minFilter = VK_FILTER_NEAREST;
|
||||||
|
break;
|
||||||
|
case SDL_SCALEMODE_PIXELART: // Uses linear sampling
|
||||||
|
case SDL_SCALEMODE_LINEAR:
|
||||||
|
samplerCreateInfo.magFilter = VK_FILTER_LINEAR;
|
||||||
|
samplerCreateInfo.minFilter = VK_FILTER_LINEAR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_SetError("Unknown scale mode: %d", scale_mode);
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
VkResult result = vkCreateSampler(data->device, &samplerCreateInfo, NULL, &data->samplers[key]);
|
||||||
|
if (result != VK_SUCCESS) {
|
||||||
|
SET_ERROR_CODE("vkCreateSampler()", result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data->samplers[key];
|
||||||
|
}
|
||||||
|
|
||||||
static bool VULKAN_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const Float4X4 *matrix, VULKAN_DrawStateCache *stateCache)
|
static bool VULKAN_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const Float4X4 *matrix, VULKAN_DrawStateCache *stateCache)
|
||||||
{
|
{
|
||||||
|
@ -3775,34 +3756,9 @@ static bool VULKAN_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand
|
||||||
|
|
||||||
VULKAN_SetupShaderConstants(renderer, cmd, texture, &constants);
|
VULKAN_SetupShaderConstants(renderer, cmd, texture, &constants);
|
||||||
|
|
||||||
switch (cmd->data.draw.texture_scale_mode) {
|
textureSampler = VULKAN_GetSampler(rendererData, cmd->data.draw.texture_scale_mode, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
|
||||||
case SDL_SCALEMODE_NEAREST:
|
if (textureSampler == VK_NULL_HANDLE) {
|
||||||
switch (cmd->data.draw.texture_address_mode) {
|
return false;
|
||||||
case SDL_TEXTURE_ADDRESS_CLAMP:
|
|
||||||
textureSampler = rendererData->samplers[VULKAN_SAMPLER_NEAREST_CLAMP];
|
|
||||||
break;
|
|
||||||
case SDL_TEXTURE_ADDRESS_WRAP:
|
|
||||||
textureSampler = rendererData->samplers[VULKAN_SAMPLER_NEAREST_WRAP];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return SDL_SetError("Unknown texture address mode: %d", cmd->data.draw.texture_address_mode);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SDL_SCALEMODE_PIXELART: // Uses linear sampling
|
|
||||||
case SDL_SCALEMODE_LINEAR:
|
|
||||||
switch (cmd->data.draw.texture_address_mode) {
|
|
||||||
case SDL_TEXTURE_ADDRESS_CLAMP:
|
|
||||||
textureSampler = rendererData->samplers[VULKAN_SAMPLER_LINEAR_CLAMP];
|
|
||||||
break;
|
|
||||||
case SDL_TEXTURE_ADDRESS_WRAP:
|
|
||||||
textureSampler = rendererData->samplers[VULKAN_SAMPLER_LINEAR_WRAP];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return SDL_SetError("Unknown texture address mode: %d", cmd->data.draw.texture_address_mode);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return SDL_SetError("Unknown scale mode: %d", cmd->data.draw.texture_scale_mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (textureData->mainImage.imageLayout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
|
if (textureData->mainImage.imageLayout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue