From: Anton Baskanov baskanov@gmail.com
--- dlls/wined3d/buffer.c | 108 ++++++++++++++++++++++++++++++--- dlls/wined3d/wined3d.spec | 1 + dlls/wined3d/wined3d_private.h | 3 + include/wine/wined3d.h | 19 ++++++ 4 files changed, 124 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 1a953f8e218..babbd0d0968 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -1685,8 +1685,9 @@ static HRESULT wined3d_streaming_buffer_prepare(struct wined3d_device *device, return hr; }
-HRESULT CDECL wined3d_streaming_buffer_upload(struct wined3d_device *device, struct wined3d_streaming_buffer *buffer, - const void *data, unsigned int size, unsigned int stride, unsigned int *ret_pos) +static HRESULT wined3d_streaming_buffer_map(struct wined3d_device *device, + struct wined3d_streaming_buffer *buffer, unsigned int size, unsigned int stride, + void **ret_data, unsigned int *ret_pos) { unsigned int map_flags = WINED3D_MAP_WRITE; struct wined3d_resource *resource; @@ -1695,9 +1696,6 @@ HRESULT CDECL wined3d_streaming_buffer_upload(struct wined3d_device *device, str struct wined3d_box box; HRESULT hr;
- TRACE("device %p, buffer %p, data %p, size %u, stride %u, ret_pos %p.\n", - device, buffer, data, size, stride, ret_pos); - if (FAILED(hr = wined3d_streaming_buffer_prepare(device, buffer, size))) return hr; resource = &buffer->buffer->resource; @@ -1719,8 +1717,104 @@ HRESULT CDECL wined3d_streaming_buffer_upload(struct wined3d_device *device, str wined3d_box_set(&box, pos, 0, pos + size, 1, 0, 1); if (SUCCEEDED(hr = wined3d_resource_map(resource, 0, &map_desc, &box, map_flags))) { - memcpy(map_desc.data, data, size); - wined3d_resource_unmap(resource, 0); + *ret_data = map_desc.data; + *ret_pos = pos; + } + return hr; +} + +HRESULT CDECL wined3d_streaming_buffer_upload(struct wined3d_device *device, struct wined3d_streaming_buffer *buffer, + const void *data, unsigned int size, unsigned int stride, unsigned int *ret_pos) +{ + unsigned int pos; + void *dst_data; + HRESULT hr; + + TRACE("device %p, buffer %p, data %p, size %u, stride %u, ret_pos %p.\n", + device, buffer, data, size, stride, ret_pos); + + if (SUCCEEDED(hr = wined3d_streaming_buffer_map(device, buffer, size, stride, &dst_data, &pos))) + { + memcpy(dst_data, data, size); + wined3d_resource_unmap(&buffer->buffer->resource, 0); + *ret_pos = pos; + buffer->pos = pos + size; + } + return hr; +} + +static void pack_strided_data(BYTE *dst, unsigned int count, const struct wined3d_draw_primitive_strided_data *src, DWORD fvf) +{ + DWORD i, tex, offset; + + for (i = 0; i < count; i++) + { + /* The contents of the strided data are determined by the fvf, + * not by the members set in src. So it's valid + * to have diffuse.data set to 0xdeadbeef if the diffuse flag is + * not set in the fvf. */ + if (fvf & WINED3DFVF_POSITION_MASK) + { + offset = i * src->position.stride; + if (fvf & WINED3DFVF_XYZRHW) + { + memcpy(dst, ((BYTE *)src->position.data) + offset, 4 * sizeof(float)); + dst += 4 * sizeof(float); + } + else + { + memcpy(dst, ((BYTE *)src->position.data) + offset, 3 * sizeof(float)); + dst += 3 * sizeof(float); + } + } + + if (fvf & WINED3DFVF_NORMAL) + { + offset = i * src->normal.stride; + memcpy(dst, ((BYTE *)src->normal.data) + offset, 3 * sizeof(float)); + dst += 3 * sizeof(float); + } + + if (fvf & WINED3DFVF_DIFFUSE) + { + offset = i * src->diffuse.stride; + memcpy(dst, ((BYTE *)src->diffuse.data) + offset, sizeof(DWORD)); + dst += sizeof(DWORD); + } + + if (fvf & WINED3DFVF_SPECULAR) + { + offset = i * src->specular.stride; + memcpy(dst, ((BYTE *)src->specular.data) + offset, sizeof(DWORD)); + dst += sizeof(DWORD); + } + + for (tex = 0; tex < GET_TEXCOUNT_FROM_FVF(fvf); ++tex) + { + DWORD attrib_count = GET_TEXCOORD_SIZE_FROM_FVF(fvf, tex); + offset = i * src->texcoords[tex].stride; + memcpy(dst, ((BYTE *)src->texcoords[tex].data) + offset, attrib_count * sizeof(float)); + dst += attrib_count * sizeof(float); + } + } +} + +HRESULT CDECL wined3d_streaming_buffer_upload_strided(struct wined3d_device *device, struct wined3d_streaming_buffer *buffer, + DWORD fvf, const struct wined3d_draw_primitive_strided_data *data, unsigned int count, unsigned int stride, unsigned int *ret_pos) +{ + unsigned int size, pos; + void *dst_data; + HRESULT hr; + + TRACE("device %p, buffer %p, fvf %x, data %p, count %u, ret_pos %p.\n", + device, buffer, fvf, data, count, ret_pos); + + size = count * stride; + + if (SUCCEEDED(hr = wined3d_streaming_buffer_map(device, buffer, size, stride, &dst_data, &pos))) + { + pack_strided_data(dst_data, count, data, fvf); + wined3d_resource_unmap(&buffer->buffer->resource, 0); *ret_pos = pos; buffer->pos = pos + size; } diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index e6126faf838..ee65fc7d4db 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -261,6 +261,7 @@ @ cdecl wined3d_stateblock_set_vs_consts_i(ptr long long ptr)
@ cdecl wined3d_streaming_buffer_upload(ptr ptr ptr long long ptr) +@ cdecl wined3d_streaming_buffer_upload_strided(ptr ptr long ptr long long ptr)
@ cdecl wined3d_swapchain_create(ptr ptr ptr ptr ptr ptr) @ cdecl wined3d_swapchain_decref(ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index b7d3b579ed2..7c7279434ba 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1864,6 +1864,9 @@ void dispatch_compute(struct wined3d_device *device, const struct wined3d_state
#define eps 1e-8f
+#define GET_TEXCOUNT_FROM_FVF(d3dvtVertexType) \ + (((d3dvtVertexType) & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT) + #define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \ (((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index a18dcda45be..5bb93aa720c 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1593,6 +1593,8 @@ enum wined3d_memory_segment_group #define WINED3D_MAX_RENDER_TARGETS 8 #define WINED3D_MAX_CONSTANT_BUFFER_SIZE 4096
+#define WINED3D_DP_MAX_TEXCOORDS 8 + struct wined3d_display_mode { UINT width; @@ -2283,6 +2285,21 @@ struct wined3d_streaming_buffer unsigned int bind_flags; };
+struct wined3d_dp_ptr_stride +{ + void *data; + DWORD stride; +}; + +struct wined3d_draw_primitive_strided_data +{ + struct wined3d_dp_ptr_stride position; + struct wined3d_dp_ptr_stride normal; + struct wined3d_dp_ptr_stride diffuse; + struct wined3d_dp_ptr_stride specular; + struct wined3d_dp_ptr_stride texcoords[WINED3D_DP_MAX_TEXCOORDS]; +}; + void __stdcall wined3d_mutex_lock(void); void __stdcall wined3d_mutex_unlock(void);
@@ -2790,6 +2807,8 @@ HRESULT __cdecl wined3d_stateblock_set_vs_consts_i(struct wined3d_stateblock *st
HRESULT __cdecl wined3d_streaming_buffer_upload(struct wined3d_device *device, struct wined3d_streaming_buffer *buffer, const void *data, unsigned int size, unsigned int stride, unsigned int *pos); +HRESULT __cdecl wined3d_streaming_buffer_upload_strided(struct wined3d_device *device, struct wined3d_streaming_buffer *buffer, + DWORD fvf, const struct wined3d_draw_primitive_strided_data *data, unsigned int count, unsigned int stride, unsigned int *pos);
HRESULT __cdecl wined3d_swapchain_create(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,