VIDEO/THREAD: Fix 64-bit pointer truncation in texture handle pipeline

The threaded video wrapper's custom command pipeline used
32-bit types for texture handles:

  - custom_command_method_t returned int (32-bit)
  - custom_command.return_value was int (32-bit)
  - video_thread_texture_handle returned unsigned (32-bit)

On 64-bit platforms, texture handles are pointers (uintptr_t).
When a D3D9 COM pointer has upper 32 bits set (e.g.
0x0000020C4E7E2800), the return value is truncated to
0x4E7E2800.  The unload path then calls Release() on this
truncated pointer, crashing with an access violation.

This is the root cause of the D3D9 HLSL/Cg crash when running
with threaded video on 64-bit Windows.  It affects any driver
whose GPU allocations return addresses above 4GB.

Fix: change the entire pipeline to use uintptr_t:

  video_thread_wrapper.h:
    - custom_command_method_t returns uintptr_t
    - custom_command.return_value is uintptr_t
    - video_thread_texture_handle returns uintptr_t

  video_thread_wrapper.c:
    - Matching implementation change

  All video drivers + font_driver.c:
    - All _wrap callback functions return uintptr_t

14 files changed, 28 insertions, 28 deletions.
This commit is contained in:
U-DESKTOP-SPFP6AQ\twistedtechre committed 2026-04-16 22:09:49 +02:00
1 parent c4a7aec8e6
commit b1dc1f3467
14 files changed
+28 -28

No files matched your search

+2 -2
View File
@@ -3666,7 +3666,7 @@ static void d3d10_gfx_unload_texture_internal(uintptr_t handle)
}
#ifdef HAVE_THREADS
static int d3d10_texture_load_wrap(void *data)
static uintptr_t d3d10_texture_load_wrap(void *data)
{
d3d10_texture_cmd_t *cmd = (d3d10_texture_cmd_t*)data;
cmd->handle = d3d10_gfx_load_texture_internal(
@@ -3674,7 +3674,7 @@ static int d3d10_texture_load_wrap(void *data)
return 0;
}
static int d3d10_texture_unload_wrap(void *data)
static uintptr_t d3d10_texture_unload_wrap(void *data)
{
d3d10_texture_cmd_t *cmd = (d3d10_texture_cmd_t*)data;
d3d10_gfx_unload_texture_internal(cmd->handle);
+2 -2
View File
@@ -5277,7 +5277,7 @@ static void d3d11_gfx_unload_texture_internal(uintptr_t handle)
}
#ifdef HAVE_THREADS
static int d3d11_texture_load_wrap(void *data)
static uintptr_t d3d11_texture_load_wrap(void *data)
{
d3d11_texture_cmd_t *cmd = (d3d11_texture_cmd_t*)data;
cmd->handle = d3d11_gfx_load_texture_internal(
@@ -5285,7 +5285,7 @@ static int d3d11_texture_load_wrap(void *data)
return 0;
}
static int d3d11_texture_unload_wrap(void *data)
static uintptr_t d3d11_texture_unload_wrap(void *data)
{
d3d11_texture_cmd_t *cmd = (d3d11_texture_cmd_t*)data;
d3d11_gfx_unload_texture_internal(cmd->handle);
+2 -2
View File
@@ -6309,7 +6309,7 @@ static void d3d12_gfx_unload_texture_internal(
* return channel) because uintptr_t may be 64-bit while the
* command's return_value is int -- truncation would corrupt
* pointer-valued handles on 64-bit Windows. */
static int d3d12_texture_load_wrap(void *data)
static uintptr_t d3d12_texture_load_wrap(void *data)
{
d3d12_texture_cmd_t *cmd = (d3d12_texture_cmd_t*)data;
cmd->handle = d3d12_gfx_load_texture_internal(
@@ -6317,7 +6317,7 @@ static int d3d12_texture_load_wrap(void *data)
return 0;
}
static int d3d12_texture_unload_wrap(void *data)
static uintptr_t d3d12_texture_unload_wrap(void *data)
{
d3d12_texture_cmd_t *cmd = (d3d12_texture_cmd_t*)data;
d3d12_gfx_unload_texture_internal(cmd->d3d12, cmd->handle);
+2 -2
View File
@@ -2098,7 +2098,7 @@ static void d3d8_video_texture_load_d3d(
*id = (uintptr_t)tex;
}
static int d3d8_video_texture_load_wrap_d3d(void *data)
static uintptr_t d3d8_video_texture_load_wrap_d3d(void *data)
{
uintptr_t id = 0;
struct d3d8_texture_info *info = (struct d3d8_texture_info*)data;
@@ -2126,7 +2126,7 @@ static uintptr_t d3d8_load_texture(void *video_data, void *data,
return id;
}
static int d3d8_video_texture_unload_wrap_d3d(void *data)
static uintptr_t d3d8_video_texture_unload_wrap_d3d(void *data)
{
uintptr_t id = (uintptr_t)data;
if (id)
+2 -2
View File
@@ -569,7 +569,7 @@ static void d3d9_video_texture_load_d3d(
}
#ifdef HAVE_THREADS
static int d3d9_cg_video_texture_load_wrap_d3d(void *data)
static uintptr_t d3d9_cg_video_texture_load_wrap_d3d(void *data)
{
uintptr_t id = 0;
struct d3d9_texture_info *info = (struct d3d9_texture_info*)data;
@@ -601,7 +601,7 @@ static uintptr_t d3d9_cg_load_texture(void *video_data, void *data,
}
#ifdef HAVE_THREADS
static int d3d9_cg_video_texture_unload_wrap_d3d(void *data)
static uintptr_t d3d9_cg_video_texture_unload_wrap_d3d(void *data)
{
uintptr_t id = (uintptr_t)data;
if (id)
+2 -2
View File
@@ -7880,7 +7880,7 @@ static void d3d9_hlsl_video_texture_load_d3d(
}
#ifdef HAVE_THREADS
static int d3d9_hlsl_video_texture_load_wrap_d3d(void *data)
static uintptr_t d3d9_hlsl_video_texture_load_wrap_d3d(void *data)
{
uintptr_t id = 0;
struct d3d9_texture_info *info = (struct d3d9_texture_info*)data;
@@ -7912,7 +7912,7 @@ uintptr_t d3d9_hlsl_load_texture(void *video_data, void *data,
}
#ifdef HAVE_THREADS
static int d3d9_hlsl_video_texture_unload_wrap_d3d(void *data)
static uintptr_t d3d9_hlsl_video_texture_unload_wrap_d3d(void *data)
{
uintptr_t id = (uintptr_t)data;
if (id)
+2 -2
View File
@@ -2180,7 +2180,7 @@ typedef struct
void *payload;
} gl1_texture_cmd_t;
static int video_texture_load_wrap_gl1(void *data)
static uintptr_t video_texture_load_wrap_gl1(void *data)
{
uintptr_t id = 0;
gl1_texture_cmd_t *cmd = (gl1_texture_cmd_t*)data;
@@ -2196,7 +2196,7 @@ static int video_texture_load_wrap_gl1(void *data)
return (int)id;
}
static int video_texture_unload_wrap_gl1(void *data)
static uintptr_t video_texture_unload_wrap_gl1(void *data)
{
GLuint glid;
gl1_texture_cmd_t *cmd = (gl1_texture_cmd_t*)data;
+3 -3
View File
@@ -5333,7 +5333,7 @@ typedef struct
void *payload;
} gl2_texture_cmd_t;
static int video_texture_load_wrap_gl2_mipmap(void *data)
static uintptr_t video_texture_load_wrap_gl2_mipmap(void *data)
{
uintptr_t id = 0;
gl2_texture_cmd_t *cmd = (gl2_texture_cmd_t*)data;
@@ -5349,7 +5349,7 @@ static int video_texture_load_wrap_gl2_mipmap(void *data)
return (int)id;
}
static int video_texture_load_wrap_gl2(void *data)
static uintptr_t video_texture_load_wrap_gl2(void *data)
{
uintptr_t id = 0;
gl2_texture_cmd_t *cmd = (gl2_texture_cmd_t*)data;
@@ -5365,7 +5365,7 @@ static int video_texture_load_wrap_gl2(void *data)
return (int)id;
}
static int video_texture_unload_wrap_gl2(void *data)
static uintptr_t video_texture_unload_wrap_gl2(void *data)
{
GLuint glid;
gl2_texture_cmd_t *cmd = (gl2_texture_cmd_t*)data;
+3 -3
View File
@@ -4591,7 +4591,7 @@ typedef struct
void *payload;
} gl3_texture_cmd_t;
static int video_texture_load_wrap_gl3_mipmap(void *data)
static uintptr_t video_texture_load_wrap_gl3_mipmap(void *data)
{
GLuint id = 0;
gl3_texture_cmd_t *cmd = (gl3_texture_cmd_t*)data;
@@ -4607,7 +4607,7 @@ static int video_texture_load_wrap_gl3_mipmap(void *data)
return (int)id;
}
static int video_texture_load_wrap_gl3(void *data)
static uintptr_t video_texture_load_wrap_gl3(void *data)
{
GLuint id = 0;
gl3_texture_cmd_t *cmd = (gl3_texture_cmd_t*)data;
@@ -4623,7 +4623,7 @@ static int video_texture_load_wrap_gl3(void *data)
return (int)id;
}
static int video_texture_unload_wrap_gl3(void *data)
static uintptr_t video_texture_unload_wrap_gl3(void *data)
{
GLuint glid;
gl3_texture_cmd_t *cmd = (gl3_texture_cmd_t*)data;
+2 -2
View File
@@ -1667,7 +1667,7 @@ typedef struct
uintptr_t handle;
} rsx_texture_cmd_t;
static int rsx_texture_load_wrap(void *data)
static uintptr_t rsx_texture_load_wrap(void *data)
{
rsx_texture_cmd_t *cmd = (rsx_texture_cmd_t*)data;
cmd->handle = rsx_load_texture_internal(
@@ -1675,7 +1675,7 @@ static int rsx_texture_load_wrap(void *data)
return 0;
}
static int rsx_texture_unload_wrap(void *data)
static uintptr_t rsx_texture_unload_wrap(void *data)
{
rsx_texture_cmd_t *cmd = (rsx_texture_cmd_t*)data;
rsx_unload_texture_internal(cmd->video_data, cmd->handle);
+1 -1
View File
@@ -7645,7 +7645,7 @@ static void vulkan_unload_texture_internal(vk_t *vk, uintptr_t handle)
#ifdef HAVE_THREADS
/* Wrap function invoked on the video thread via
* CMD_CUSTOM_COMMAND. Returns 0 (ignored). */
static int vulkan_texture_unload_wrap(void *data)
static uintptr_t vulkan_texture_unload_wrap(void *data)
{
vulkan_texture_cmd_t *cmd = (vulkan_texture_cmd_t*)data;
vulkan_unload_texture_internal(cmd->vk, cmd->handle);
+1 -1
View File
@@ -909,7 +909,7 @@ typedef struct
bool is_threaded;
} font_free_cmd_t;
static int font_driver_free_wrap(void *data)
static uintptr_t font_driver_free_wrap(void *data)
{
font_free_cmd_t *cmd = (font_free_cmd_t*)data;
if (cmd->renderer && cmd->renderer->free)
+1 -1
View File
@@ -1471,7 +1471,7 @@ bool video_thread_font_init(const void **font_driver, void **font_handle,
return pkt.data.font_init.return_value;
}
unsigned video_thread_texture_handle(void *data, custom_command_method_t func)
uintptr_t video_thread_texture_handle(void *data, custom_command_method_t func)
{
thread_packet_t pkt;
video_driver_state_t *video_st = video_state_get_ptr();
+3 -3
View File
@@ -67,7 +67,7 @@ enum thread_cmd
CMD_DUMMY = INT_MAX
};
typedef int (*custom_command_method_t)(void*);
typedef uintptr_t (*custom_command_method_t)(void*);
typedef bool (*custom_font_command_method_t)(const void **font_driver,
void **font_handle, void *video_data, const char *font_path,
@@ -140,7 +140,7 @@ typedef struct thread_packet
{
custom_command_method_t method;
void* data;
int return_value;
uintptr_t return_value;
} custom_command;
struct
@@ -272,7 +272,7 @@ bool video_thread_font_init(
custom_font_command_method_t func,
bool is_threaded);
unsigned video_thread_texture_handle(void *data,
uintptr_t video_thread_texture_handle(void *data,
custom_command_method_t func);
/* Barrier: wait until the video thread is idle (no pending frame).