wined3d: Implement wined3d_device_update_surface() on top of surface_upload_data().
This commit is contained in:
parent
4b2bfb4a8b
commit
b9133d7de0
|
@ -4736,13 +4736,12 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device,
|
||||||
const struct wined3d_format *dst_format;
|
const struct wined3d_format *dst_format;
|
||||||
const struct wined3d_gl_info *gl_info;
|
const struct wined3d_gl_info *gl_info;
|
||||||
struct wined3d_context *context;
|
struct wined3d_context *context;
|
||||||
const unsigned char *data;
|
struct wined3d_bo_address data;
|
||||||
UINT update_w, update_h;
|
|
||||||
CONVERT_TYPES convert;
|
|
||||||
UINT src_w, src_h;
|
|
||||||
UINT dst_x, dst_y;
|
|
||||||
DWORD sampler;
|
|
||||||
struct wined3d_format format;
|
struct wined3d_format format;
|
||||||
|
CONVERT_TYPES convert;
|
||||||
|
DWORD sampler;
|
||||||
|
POINT p;
|
||||||
|
RECT r;
|
||||||
|
|
||||||
TRACE("device %p, src_surface %p, src_rect %s, dst_surface %p, dst_point %s.\n",
|
TRACE("device %p, src_surface %p, src_rect %s, dst_surface %p, dst_point %s.\n",
|
||||||
device, src_surface, wine_dbgstr_rect(src_rect),
|
device, src_surface, wine_dbgstr_rect(src_rect),
|
||||||
|
@ -4764,8 +4763,12 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device,
|
||||||
return WINED3DERR_INVALIDCALL;
|
return WINED3DERR_INVALIDCALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dst_x = dst_point ? dst_point->x : 0;
|
if (!dst_point)
|
||||||
dst_y = dst_point ? dst_point->y : 0;
|
{
|
||||||
|
p.x = 0;
|
||||||
|
p.y = 0;
|
||||||
|
dst_point = &p;
|
||||||
|
}
|
||||||
|
|
||||||
/* This call loads the OpenGL surface directly, instead of copying the
|
/* This call loads the OpenGL surface directly, instead of copying the
|
||||||
* surface to the destination's sysmem copy. If surface conversion is
|
* surface to the destination's sysmem copy. If surface conversion is
|
||||||
|
@ -4773,7 +4776,7 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device,
|
||||||
* loading. */
|
* loading. */
|
||||||
d3dfmt_get_conv(dst_surface, FALSE, TRUE, &format, &convert);
|
d3dfmt_get_conv(dst_surface, FALSE, TRUE, &format, &convert);
|
||||||
if (convert != NO_CONVERSION || format.convert)
|
if (convert != NO_CONVERSION || format.convert)
|
||||||
return wined3d_surface_bltfast(dst_surface, dst_x, dst_y, src_surface, src_rect, 0);
|
return wined3d_surface_bltfast(dst_surface, dst_point->x, dst_point->y, src_surface, src_rect, 0);
|
||||||
|
|
||||||
context = context_acquire(device, NULL);
|
context = context_acquire(device, NULL);
|
||||||
gl_info = context->gl_info;
|
gl_info = context->gl_info;
|
||||||
|
@ -4787,73 +4790,24 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device,
|
||||||
surface_internal_preload(dst_surface, SRGB_RGB);
|
surface_internal_preload(dst_surface, SRGB_RGB);
|
||||||
surface_bind(dst_surface, gl_info, FALSE);
|
surface_bind(dst_surface, gl_info, FALSE);
|
||||||
|
|
||||||
src_w = src_surface->resource.width;
|
if (!src_rect)
|
||||||
src_h = src_surface->resource.height;
|
|
||||||
update_w = src_rect ? src_rect->right - src_rect->left : src_w;
|
|
||||||
update_h = src_rect ? src_rect->bottom - src_rect->top : src_h;
|
|
||||||
|
|
||||||
data = src_surface->resource.allocatedMemory;
|
|
||||||
if (!data) ERR("Source surface has no allocated memory, but should be a sysmem surface.\n");
|
|
||||||
|
|
||||||
ENTER_GL();
|
|
||||||
|
|
||||||
if (dst_format->flags & WINED3DFMT_FLAG_COMPRESSED)
|
|
||||||
{
|
{
|
||||||
UINT row_length = wined3d_format_calculate_size(src_format, 1, update_w, 1);
|
r.left = 0;
|
||||||
UINT row_count = (update_h + src_format->block_height - 1) / src_format->block_height;
|
r.top = 0;
|
||||||
UINT src_pitch = wined3d_format_calculate_size(src_format, 1, src_w, 1);
|
r.right = src_surface->resource.width;
|
||||||
|
r.bottom = src_surface->resource.height;
|
||||||
if (src_rect)
|
src_rect = &r;
|
||||||
{
|
|
||||||
data += (src_rect->top / src_format->block_height) * src_pitch;
|
|
||||||
data += (src_rect->left / src_format->block_width) * src_format->block_byte_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("glCompressedTexSubImage2DARB, target %#x, level %d, x %d, y %d, w %d, h %d, "
|
|
||||||
"format %#x, image_size %#x, data %p.\n", dst_surface->texture_target, dst_surface->texture_level,
|
|
||||||
dst_x, dst_y, update_w, update_h, dst_format->glFormat, row_count * row_length, data);
|
|
||||||
|
|
||||||
if (row_length == src_pitch)
|
|
||||||
{
|
|
||||||
GL_EXTCALL(glCompressedTexSubImage2DARB(dst_surface->texture_target, dst_surface->texture_level,
|
|
||||||
dst_x, dst_y, update_w, update_h, dst_format->glInternal, row_count * row_length, data));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UINT row, y;
|
|
||||||
|
|
||||||
/* glCompressedTexSubImage2DARB() ignores pixel store state, so we
|
|
||||||
* can't use the unpack row length like below. */
|
|
||||||
for (row = 0, y = dst_y; row < row_count; ++row)
|
|
||||||
{
|
|
||||||
GL_EXTCALL(glCompressedTexSubImage2DARB(dst_surface->texture_target, dst_surface->texture_level,
|
|
||||||
dst_x, y, update_w, src_format->block_height, dst_format->glInternal, row_length, data));
|
|
||||||
y += src_format->block_height;
|
|
||||||
data += src_pitch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checkGLcall("glCompressedTexSubImage2DARB");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (src_rect)
|
|
||||||
{
|
|
||||||
data += src_rect->top * src_w * src_format->byte_count;
|
|
||||||
data += src_rect->left * src_format->byte_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("glTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, format %#x, type %#x, data %p.\n",
|
|
||||||
dst_surface->texture_target, dst_surface->texture_level, dst_x, dst_y,
|
|
||||||
update_w, update_h, dst_format->glFormat, dst_format->glType, data);
|
|
||||||
|
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, src_w);
|
|
||||||
glTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level, dst_x, dst_y,
|
|
||||||
update_w, update_h, dst_format->glFormat, dst_format->glType, data);
|
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
||||||
checkGLcall("glTexSubImage2D");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LEAVE_GL();
|
data.buffer_object = 0;
|
||||||
|
data.addr = src_surface->resource.allocatedMemory;
|
||||||
|
|
||||||
|
if (!data.addr)
|
||||||
|
ERR("Source surface has no allocated memory, but should be a sysmem surface.\n");
|
||||||
|
|
||||||
|
surface_upload_data(dst_surface, gl_info, src_format, src_rect,
|
||||||
|
src_surface->resource.width, dst_point, FALSE, &data);
|
||||||
|
|
||||||
context_release(context);
|
context_release(context);
|
||||||
|
|
||||||
surface_modify_location(dst_surface, SFLAG_INTEXTURE, TRUE);
|
surface_modify_location(dst_surface, SFLAG_INTEXTURE, TRUE);
|
||||||
|
|
|
@ -2161,32 +2161,19 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
|
||||||
/* This call just uploads data, the caller is responsible for binding the
|
/* This call just uploads data, the caller is responsible for binding the
|
||||||
* correct texture. */
|
* correct texture. */
|
||||||
/* Context activation is done by the caller. */
|
/* Context activation is done by the caller. */
|
||||||
static void surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
|
void surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
|
||||||
const struct wined3d_format *format, BOOL srgb, const struct wined3d_bo_address *data)
|
const struct wined3d_format *format, const RECT *src_rect, UINT src_w, const POINT *dst_point,
|
||||||
|
BOOL srgb, const struct wined3d_bo_address *data)
|
||||||
{
|
{
|
||||||
GLsizei width = surface->resource.width;
|
UINT update_w = src_rect->right - src_rect->left;
|
||||||
GLsizei height = surface->resource.height;
|
UINT update_h = src_rect->bottom - src_rect->top;
|
||||||
GLenum internal;
|
|
||||||
|
|
||||||
if (srgb)
|
TRACE("surface %p, gl_info %p, format %s, src_rect %s, src_w %u, dst_point %p, srgb %#x, data {%#x:%p}.\n",
|
||||||
{
|
surface, gl_info, debug_d3dformat(format->id), wine_dbgstr_rect(src_rect), src_w,
|
||||||
internal = format->glGammaInternal;
|
wine_dbgstr_point(dst_point), srgb, data->buffer_object, data->addr);
|
||||||
}
|
|
||||||
else if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET && surface_is_offscreen(surface))
|
|
||||||
{
|
|
||||||
internal = format->rtInternal;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
internal = format->glInternal;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("surface %p, internal %#x, width %d, height %d, format %#x, type %#x, data {%#x:%p}.\n",
|
if (format->heightscale != 1.0f && format->heightscale != 0.0f)
|
||||||
surface, internal, width, height, format->glFormat, format->glType, data->buffer_object, data->addr);
|
update_h *= format->heightscale;
|
||||||
TRACE("target %#x, level %u, resource size %u.\n",
|
|
||||||
surface->texture_target, surface->texture_level, surface->resource.size);
|
|
||||||
|
|
||||||
if (format->heightscale != 1.0f && format->heightscale != 0.0f) height *= format->heightscale;
|
|
||||||
|
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
|
|
||||||
|
@ -2196,29 +2183,67 @@ static void surface_upload_data(struct wined3d_surface *surface, const struct wi
|
||||||
checkGLcall("glBindBufferARB");
|
checkGLcall("glBindBufferARB");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the correct pitch is used */
|
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
|
|
||||||
|
|
||||||
if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
|
if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
|
||||||
{
|
{
|
||||||
TRACE("Calling glCompressedTexSubImage2DARB.\n");
|
UINT row_length = wined3d_format_calculate_size(format, 1, update_w, 1);
|
||||||
|
UINT row_count = (update_h + format->block_height - 1) / format->block_height;
|
||||||
|
UINT src_pitch = wined3d_format_calculate_size(format, 1, src_w, 1);
|
||||||
|
const BYTE *addr = data->addr;
|
||||||
|
GLenum internal;
|
||||||
|
|
||||||
GL_EXTCALL(glCompressedTexSubImage2DARB(surface->texture_target, surface->texture_level,
|
addr += (src_rect->top / format->block_height) * src_pitch;
|
||||||
0, 0, width, height, internal, surface->resource.size, data->addr));
|
addr += (src_rect->left / format->block_width) * format->block_byte_count;
|
||||||
|
|
||||||
|
if (srgb)
|
||||||
|
internal = format->glGammaInternal;
|
||||||
|
else if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET && surface_is_offscreen(surface))
|
||||||
|
internal = format->rtInternal;
|
||||||
|
else
|
||||||
|
internal = format->glInternal;
|
||||||
|
|
||||||
|
TRACE("glCompressedTexSubImage2DARB, target %#x, level %d, x %d, y %d, w %d, h %d, "
|
||||||
|
"format %#x, image_size %#x, addr %p.\n", surface->texture_target, surface->texture_level,
|
||||||
|
dst_point->x, dst_point->y, update_w, update_h, internal, row_count * row_length, addr);
|
||||||
|
|
||||||
|
if (row_length == src_pitch)
|
||||||
|
{
|
||||||
|
GL_EXTCALL(glCompressedTexSubImage2DARB(surface->texture_target, surface->texture_level,
|
||||||
|
dst_point->x, dst_point->y, update_w, update_h, internal, row_count * row_length, addr));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UINT row, y;
|
||||||
|
|
||||||
|
/* glCompressedTexSubImage2DARB() ignores pixel store state, so we
|
||||||
|
* can't use the unpack row length like below. */
|
||||||
|
for (row = 0, y = dst_point->y; row < row_count; ++row)
|
||||||
|
{
|
||||||
|
GL_EXTCALL(glCompressedTexSubImage2DARB(surface->texture_target, surface->texture_level,
|
||||||
|
dst_point->x, y, update_w, format->block_height, internal, row_length, addr));
|
||||||
|
y += format->block_height;
|
||||||
|
addr += src_pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
checkGLcall("glCompressedTexSubImage2DARB");
|
checkGLcall("glCompressedTexSubImage2DARB");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TRACE("Calling glTexSubImage2D.\n");
|
const BYTE *addr = data->addr;
|
||||||
|
|
||||||
glTexSubImage2D(surface->texture_target, surface->texture_level,
|
addr += src_rect->top * src_w * format->byte_count;
|
||||||
0, 0, width, height, format->glFormat, format->glType, data->addr);
|
addr += src_rect->left * format->byte_count;
|
||||||
|
|
||||||
|
TRACE("glTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, format %#x, type %#x, addr %p.\n",
|
||||||
|
surface->texture_target, surface->texture_level, dst_point->x, dst_point->y,
|
||||||
|
update_w, update_h, format->glFormat, format->glType, addr);
|
||||||
|
|
||||||
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, src_w);
|
||||||
|
glTexSubImage2D(surface->texture_target, surface->texture_level, dst_point->x, dst_point->y,
|
||||||
|
update_w, update_h, format->glFormat, format->glType, addr);
|
||||||
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
checkGLcall("glTexSubImage2D");
|
checkGLcall("glTexSubImage2D");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the default pitch */
|
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
||||||
|
|
||||||
if (data->buffer_object)
|
if (data->buffer_object)
|
||||||
{
|
{
|
||||||
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
|
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
|
||||||
|
@ -6067,9 +6092,11 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD flag, const
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Upload from system memory */
|
/* Upload from system memory */
|
||||||
|
RECT src_rect = {0, 0, surface->resource.width, surface->resource.height};
|
||||||
BOOL srgb = flag == SFLAG_INSRGBTEX;
|
BOOL srgb = flag == SFLAG_INSRGBTEX;
|
||||||
struct wined3d_context *context = NULL;
|
struct wined3d_context *context = NULL;
|
||||||
struct wined3d_bo_address data;
|
struct wined3d_bo_address data;
|
||||||
|
POINT dst_point = {0, 0};
|
||||||
|
|
||||||
d3dfmt_get_conv(surface, TRUE /* We need color keying */,
|
d3dfmt_get_conv(surface, TRUE /* We need color keying */,
|
||||||
TRUE /* We will use textures */, &format, &convert);
|
TRUE /* We will use textures */, &format, &convert);
|
||||||
|
@ -6165,7 +6192,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD flag, const
|
||||||
|
|
||||||
data.buffer_object = surface->flags & SFLAG_PBO ? surface->pbo : 0;
|
data.buffer_object = surface->flags & SFLAG_PBO ? surface->pbo : 0;
|
||||||
data.addr = mem;
|
data.addr = mem;
|
||||||
surface_upload_data(surface, gl_info, &format, srgb, &data);
|
surface_upload_data(surface, gl_info, &format, &src_rect, width, &dst_point, srgb, &data);
|
||||||
|
|
||||||
if (context) context_release(context);
|
if (context) context_release(context);
|
||||||
|
|
||||||
|
|
|
@ -2130,6 +2130,9 @@ void surface_set_container(struct wined3d_surface *surface,
|
||||||
void surface_set_texture_name(struct wined3d_surface *surface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN;
|
void surface_set_texture_name(struct wined3d_surface *surface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN;
|
||||||
void surface_set_texture_target(struct wined3d_surface *surface, GLenum target) DECLSPEC_HIDDEN;
|
void surface_set_texture_target(struct wined3d_surface *surface, GLenum target) DECLSPEC_HIDDEN;
|
||||||
void surface_translate_drawable_coords(struct wined3d_surface *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN;
|
void surface_translate_drawable_coords(struct wined3d_surface *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN;
|
||||||
|
void surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
|
||||||
|
const struct wined3d_format *format, const RECT *src_rect, UINT src_w, const POINT *dst_point,
|
||||||
|
BOOL srgb, const struct wined3d_bo_address *data) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
void get_drawable_size_swapchain(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN;
|
void get_drawable_size_swapchain(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN;
|
||||||
void get_drawable_size_backbuffer(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN;
|
void get_drawable_size_backbuffer(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue