ReactOS 0.4.16-dev-297-gc569aee
buffer.c File Reference
#include "config.h"
#include "wine/port.h"
#include "wined3d_private.h"
Include dependency graph for buffer.c:

Go to the source code of this file.

Macros

#define WINED3D_BUFFER_HASDESC   0x01 /* A vertex description has been found. */
 
#define WINED3D_BUFFER_USE_BO   0x02 /* Use a buffer object for this buffer. */
 
#define WINED3D_BUFFER_PIN_SYSMEM   0x04 /* Keep a system memory copy for this buffer. */
 
#define WINED3D_BUFFER_DISCARD   0x08 /* A DISCARD lock has occurred since the last preload. */
 
#define WINED3D_BUFFER_APPLESYNC   0x10 /* Using sync as in GL_APPLE_flush_buffer_range. */
 
#define VB_MAXDECLCHANGES   100 /* After that number of decl changes we stop converting */
 
#define VB_RESETDECLCHANGE   1000 /* Reset the decl changecount after that number of draws */
 
#define VB_MAXFULLCONVERSIONS   5 /* Number of full conversions before we stop converting */
 
#define VB_RESETFULLCONVS   20 /* Reset full conversion counts after that number of draws */
 
#define WINED3D_BUFFER_FIXUP_D3DCOLOR   0x01
 
#define WINED3D_BUFFER_FIXUP_XYZRHW   0x02
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (d3d)
 
static void wined3d_buffer_evict_sysmem (struct wined3d_buffer *buffer)
 
static void buffer_invalidate_bo_range (struct wined3d_buffer *buffer, unsigned int offset, unsigned int size)
 
static void buffer_clear_dirty_areas (struct wined3d_buffer *This)
 
static BOOL buffer_is_dirty (const struct wined3d_buffer *buffer)
 
static BOOL buffer_is_fully_dirty (const struct wined3d_buffer *buffer)
 
static void wined3d_buffer_validate_location (struct wined3d_buffer *buffer, DWORD location)
 
static void wined3d_buffer_invalidate_range (struct wined3d_buffer *buffer, DWORD location, unsigned int offset, unsigned int size)
 
void wined3d_buffer_invalidate_location (struct wined3d_buffer *buffer, DWORD location)
 
static void buffer_bind (struct wined3d_buffer *buffer, struct wined3d_context *context)
 
static void buffer_destroy_buffer_object (struct wined3d_buffer *buffer, struct wined3d_context *context)
 
static BOOL buffer_create_buffer_object (struct wined3d_buffer *buffer, struct wined3d_context *context)
 
static BOOL buffer_process_converted_attribute (struct wined3d_buffer *buffer, const enum wined3d_buffer_conversion_type conversion_type, const struct wined3d_stream_info_element *attrib, DWORD *stride_this_run)
 
static BOOL buffer_check_attribute (struct wined3d_buffer *This, const struct wined3d_stream_info *si, const struct wined3d_state *state, UINT attrib_idx, DWORD fixup_flags, DWORD *stride_this_run)
 
static BOOL buffer_find_decl (struct wined3d_buffer *This, const struct wined3d_stream_info *si, const struct wined3d_state *state, DWORD fixup_flags)
 
static unsigned int fixup_d3dcolor (DWORD *dst_color)
 
static unsigned int fixup_transformed_pos (struct wined3d_vec4 *p)
 
ULONG CDECL wined3d_buffer_incref (struct wined3d_buffer *buffer)
 
static void wined3d_buffer_upload_ranges (struct wined3d_buffer *buffer, struct wined3d_context *context, const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges)
 
static void buffer_conversion_upload (struct wined3d_buffer *buffer, struct wined3d_context *context)
 
static BOOL wined3d_buffer_prepare_location (struct wined3d_buffer *buffer, struct wined3d_context *context, DWORD location)
 
BOOL wined3d_buffer_load_location (struct wined3d_buffer *buffer, struct wined3d_context *context, DWORD location)
 
BYTEwined3d_buffer_load_sysmem (struct wined3d_buffer *buffer, struct wined3d_context *context)
 
DWORD wined3d_buffer_get_memory (struct wined3d_buffer *buffer, struct wined3d_bo_address *data, DWORD locations)
 
static void buffer_unload (struct wined3d_resource *resource)
 
static void wined3d_buffer_drop_bo (struct wined3d_buffer *buffer)
 
static void wined3d_buffer_destroy_object (void *object)
 
ULONG CDECL wined3d_buffer_decref (struct wined3d_buffer *buffer)
 
void *CDECL wined3d_buffer_get_parent (const struct wined3d_buffer *buffer)
 
static void buffer_sync_apple (struct wined3d_buffer *buffer, DWORD flags, const struct wined3d_gl_info *gl_info)
 
static void buffer_mark_used (struct wined3d_buffer *buffer)
 
void wined3d_buffer_load (struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_state *state)
 
struct wined3d_resource *CDECL wined3d_buffer_get_resource (struct wined3d_buffer *buffer)
 
static HRESULT wined3d_buffer_map (struct wined3d_buffer *buffer, UINT offset, UINT size, BYTE **data, DWORD flags)
 
static void wined3d_buffer_unmap (struct wined3d_buffer *buffer)
 
void wined3d_buffer_copy (struct wined3d_buffer *dst_buffer, unsigned int dst_offset, struct wined3d_buffer *src_buffer, unsigned int src_offset, unsigned int size)
 
void wined3d_buffer_upload_data (struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_box *box, const void *data)
 
static ULONG buffer_resource_incref (struct wined3d_resource *resource)
 
static ULONG buffer_resource_decref (struct wined3d_resource *resource)
 
static void buffer_resource_preload (struct wined3d_resource *resource)
 
static HRESULT buffer_resource_sub_resource_map (struct wined3d_resource *resource, unsigned int sub_resource_idx, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
 
static HRESULT buffer_resource_sub_resource_map_info (struct wined3d_resource *resource, unsigned int sub_resource_idx, struct wined3d_map_info *info, DWORD flags)
 
static HRESULT buffer_resource_sub_resource_unmap (struct wined3d_resource *resource, unsigned int sub_resource_idx)
 
static GLenum buffer_type_hint_from_bind_flags (const struct wined3d_gl_info *gl_info, unsigned int bind_flags)
 
static HRESULT buffer_init (struct wined3d_buffer *buffer, struct wined3d_device *device, UINT size, DWORD usage, enum wined3d_format_id format_id, unsigned int access, unsigned int bind_flags, const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops)
 
HRESULT CDECL wined3d_buffer_create (struct wined3d_device *device, const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_buffer **buffer)
 

Variables

static const struct wined3d_resource_ops buffer_resource_ops
 

Macro Definition Documentation

◆ VB_MAXDECLCHANGES

#define VB_MAXDECLCHANGES   100 /* After that number of decl changes we stop converting */

Definition at line 38 of file buffer.c.

◆ VB_MAXFULLCONVERSIONS

#define VB_MAXFULLCONVERSIONS   5 /* Number of full conversions before we stop converting */

Definition at line 40 of file buffer.c.

◆ VB_RESETDECLCHANGE

#define VB_RESETDECLCHANGE   1000 /* Reset the decl changecount after that number of draws */

Definition at line 39 of file buffer.c.

◆ VB_RESETFULLCONVS

#define VB_RESETFULLCONVS   20 /* Reset full conversion counts after that number of draws */

Definition at line 41 of file buffer.c.

◆ WINED3D_BUFFER_APPLESYNC

#define WINED3D_BUFFER_APPLESYNC   0x10 /* Using sync as in GL_APPLE_flush_buffer_range. */

Definition at line 36 of file buffer.c.

◆ WINED3D_BUFFER_DISCARD

#define WINED3D_BUFFER_DISCARD   0x08 /* A DISCARD lock has occurred since the last preload. */

Definition at line 35 of file buffer.c.

◆ WINED3D_BUFFER_FIXUP_D3DCOLOR

#define WINED3D_BUFFER_FIXUP_D3DCOLOR   0x01

Definition at line 327 of file buffer.c.

◆ WINED3D_BUFFER_FIXUP_XYZRHW

#define WINED3D_BUFFER_FIXUP_XYZRHW   0x02

Definition at line 328 of file buffer.c.

◆ WINED3D_BUFFER_HASDESC

#define WINED3D_BUFFER_HASDESC   0x01 /* A vertex description has been found. */

Definition at line 32 of file buffer.c.

◆ WINED3D_BUFFER_PIN_SYSMEM

#define WINED3D_BUFFER_PIN_SYSMEM   0x04 /* Keep a system memory copy for this buffer. */

Definition at line 34 of file buffer.c.

◆ WINED3D_BUFFER_USE_BO

#define WINED3D_BUFFER_USE_BO   0x02 /* Use a buffer object for this buffer. */

Definition at line 33 of file buffer.c.

Function Documentation

◆ buffer_bind()

static void buffer_bind ( struct wined3d_buffer buffer,
struct wined3d_context context 
)
static

Definition at line 136 of file buffer.c.

137{
138 context_bind_bo(context, buffer->buffer_type_hint, buffer->buffer_object);
139}
void context_bind_bo(struct wined3d_context *context, GLenum binding, GLuint name)
Definition: context.c:2724
GLuint buffer
Definition: glext.h:5915
Definition: http.c:7252

Referenced by buffer_create_buffer_object(), wined3d_buffer_load_location(), wined3d_buffer_map(), wined3d_buffer_unmap(), and wined3d_buffer_upload_ranges().

◆ buffer_check_attribute()

static BOOL buffer_check_attribute ( struct wined3d_buffer This,
const struct wined3d_stream_info si,
const struct wined3d_state state,
UINT  attrib_idx,
DWORD  fixup_flags,
DWORD stride_this_run 
)
static

Definition at line 330 of file buffer.c.

332{
333 const struct wined3d_stream_info_element *attrib = &si->elements[attrib_idx];
335 BOOL ret = FALSE;
336
337 /* Ignore attributes that do not have our vbo. After that check we can be sure that the attribute is
338 * there, on nonexistent attribs the vbo is 0.
339 */
340 if (!(si->use_map & (1u << attrib_idx))
341 || state->streams[attrib->stream_idx].buffer != This)
342 return FALSE;
343
344 format = attrib->format->id;
345 /* Look for newly appeared conversion */
347 {
348 ret = buffer_process_converted_attribute(This, CONV_D3DCOLOR, attrib, stride_this_run);
349 }
350 else if (fixup_flags & WINED3D_BUFFER_FIXUP_XYZRHW && si->position_transformed)
351 {
353 {
354 FIXME("Unexpected format %s for transformed position.\n", debug_d3dformat(format));
355 return FALSE;
356 }
357
358 ret = buffer_process_converted_attribute(This, CONV_POSITIONT, attrib, stride_this_run);
359 }
360 else if (This->conversion_map)
361 {
362 ret = buffer_process_converted_attribute(This, CONV_NONE, attrib, stride_this_run);
363 }
364
365 return ret;
366}
static int state
Definition: maze.c:121
#define FIXME(fmt,...)
Definition: precomp.h:53
#define FALSE
Definition: types.h:117
#define WINED3D_BUFFER_FIXUP_D3DCOLOR
Definition: buffer.c:327
static BOOL buffer_process_converted_attribute(struct wined3d_buffer *buffer, const enum wined3d_buffer_conversion_type conversion_type, const struct wined3d_stream_info_element *attrib, DWORD *stride_this_run)
Definition: buffer.c:272
#define WINED3D_BUFFER_FIXUP_XYZRHW
Definition: buffer.c:328
const char * debug_d3dformat(enum wined3d_format_id format_id)
Definition: utils.c:3980
unsigned int BOOL
Definition: ntddk_ex.h:94
Definition: format.c:58
const struct wined3d_format * format
struct wined3d_stream_info_element elements[MAX_ATTRIBS]
int ret
wined3d_format_id
Definition: wined3d.h:106
@ WINED3DFMT_B8G8R8A8_UNORM
Definition: wined3d.h:223
@ WINED3DFMT_R32G32B32A32_FLOAT
Definition: wined3d.h:136
@ CONV_NONE
@ CONV_POSITIONT
@ CONV_D3DCOLOR

Referenced by buffer_find_decl().

◆ buffer_clear_dirty_areas()

static void buffer_clear_dirty_areas ( struct wined3d_buffer This)
inlinestatic

Definition at line 85 of file buffer.c.

86{
87 This->modified_areas = 0;
88}

Referenced by buffer_create_buffer_object(), buffer_unload(), wined3d_buffer_unmap(), and wined3d_buffer_validate_location().

◆ buffer_conversion_upload()

static void buffer_conversion_upload ( struct wined3d_buffer buffer,
struct wined3d_context context 
)
static

Definition at line 552 of file buffer.c.

553{
554 unsigned int i, j, range_idx, start, end, vertex_count;
555 BYTE *data;
556
558 {
559 ERR("Failed to load system memory.\n");
560 return;
561 }
563
564 /* Now for each vertex in the buffer that needs conversion. */
565 vertex_count = buffer->resource.size / buffer->stride;
566
567 if (!(data = heap_alloc(buffer->resource.size)))
568 {
569 ERR("Out of memory.\n");
570 return;
571 }
572
573 for (range_idx = 0; range_idx < buffer->modified_areas; ++range_idx)
574 {
575 start = buffer->maps[range_idx].offset;
576 end = start + buffer->maps[range_idx].size;
577
578 memcpy(data + start, (BYTE *)buffer->resource.heap_memory + start, end - start);
579 for (i = start / buffer->stride; i < min((end / buffer->stride) + 1, vertex_count); ++i)
580 {
581 for (j = 0; j < buffer->stride;)
582 {
583 switch (buffer->conversion_map[j])
584 {
585 case CONV_NONE:
586 /* Done already */
587 j += sizeof(DWORD);
588 break;
589 case CONV_D3DCOLOR:
590 j += fixup_d3dcolor((DWORD *) (data + i * buffer->stride + j));
591 break;
592 case CONV_POSITIONT:
593 j += fixup_transformed_pos((struct wined3d_vec4 *) (data + i * buffer->stride + j));
594 break;
595 default:
596 FIXME("Unimplemented conversion %d in shifted conversion.\n", buffer->conversion_map[j]);
597 ++j;
598 }
599 }
600 }
601 }
602
603 wined3d_buffer_upload_ranges(buffer, context, data, 0, buffer->modified_areas, buffer->maps);
604
606}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define ERR(fmt,...)
Definition: precomp.h:57
static unsigned int fixup_transformed_pos(struct wined3d_vec4 *p)
Definition: buffer.c:510
static void wined3d_buffer_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context, const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges)
Definition: buffer.c:535
static unsigned int fixup_d3dcolor(DWORD *dst_color)
Definition: buffer.c:489
#define WINED3D_BUFFER_PIN_SYSMEM
Definition: buffer.c:34
BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer, struct wined3d_context *context, DWORD location)
Definition: buffer.c:641
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint start
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
int vertex_count
Definition: d3drm.c:3367
#define min(a, b)
Definition: monoChain.cc:55
#define DWORD
Definition: nt_native.h:44
#define WINED3D_LOCATION_SYSMEM
unsigned char BYTE
Definition: xxhash.c:193

Referenced by wined3d_buffer_load_location().

◆ buffer_create_buffer_object()

static BOOL buffer_create_buffer_object ( struct wined3d_buffer buffer,
struct wined3d_context context 
)
static

Definition at line 197 of file buffer.c.

198{
199 const struct wined3d_gl_info *gl_info = context->gl_info;
200 GLenum gl_usage = GL_STATIC_DRAW;
202
203 TRACE("Creating an OpenGL buffer object for wined3d_buffer %p with usage %s.\n",
204 buffer, debug_d3dusage(buffer->resource.usage));
205
206 /* Make sure that the gl error is cleared. Do not use checkGLcall
207 * here because checkGLcall just prints a fixme and continues. However,
208 * if an error during VBO creation occurs we can fall back to non-VBO operation
209 * with full functionality(but performance loss).
210 */
211 while (gl_info->gl_ops.gl.p_glGetError() != GL_NO_ERROR);
212
213 /* Basically the FVF parameter passed to CreateVertexBuffer is no good.
214 * The vertex declaration from the device determines how the data in the
215 * buffer is interpreted. This means that on each draw call the buffer has
216 * to be verified to check if the rhw and color values are in the correct
217 * format. */
218
219 GL_EXTCALL(glGenBuffers(1, &buffer->buffer_object));
220 error = gl_info->gl_ops.gl.p_glGetError();
221 if (!buffer->buffer_object || error != GL_NO_ERROR)
222 {
223 ERR("Failed to create a BO with error %s (%#x).\n", debug_glerror(error), error);
224 goto fail;
225 }
226
228 error = gl_info->gl_ops.gl.p_glGetError();
229 if (error != GL_NO_ERROR)
230 {
231 ERR("Failed to bind the BO with error %s (%#x).\n", debug_glerror(error), error);
232 goto fail;
233 }
234
235 if (buffer->resource.usage & WINED3DUSAGE_DYNAMIC)
236 {
237 TRACE("Buffer has WINED3DUSAGE_DYNAMIC set.\n");
238 gl_usage = GL_STREAM_DRAW_ARB;
239
241 {
242 GL_EXTCALL(glBufferParameteriAPPLE(buffer->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE));
243 GL_EXTCALL(glBufferParameteriAPPLE(buffer->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE));
244 checkGLcall("glBufferParameteriAPPLE");
246 }
247 /* No setup is needed here for GL_ARB_map_buffer_range. */
248 }
249
250 GL_EXTCALL(glBufferData(buffer->buffer_type_hint, buffer->resource.size, NULL, gl_usage));
251 error = gl_info->gl_ops.gl.p_glGetError();
252 if (error != GL_NO_ERROR)
253 {
254 ERR("glBufferData failed with error %s (%#x).\n", debug_glerror(error), error);
255 goto fail;
256 }
257
258 buffer->buffer_object_usage = gl_usage;
260
261 return TRUE;
262
263fail:
264 /* Clean up all BO init, but continue because we can work without a BO :-) */
265 ERR("Failed to create a buffer object. Continuing, but performance issues may occur.\n");
266 buffer->flags &= ~WINED3D_BUFFER_USE_BO;
269 return FALSE;
270}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
static void buffer_clear_dirty_areas(struct wined3d_buffer *This)
Definition: buffer.c:85
static void buffer_destroy_buffer_object(struct wined3d_buffer *buffer, struct wined3d_context *context)
Definition: buffer.c:142
#define WINED3D_BUFFER_APPLESYNC
Definition: buffer.c:36
static void buffer_bind(struct wined3d_buffer *buffer, struct wined3d_context *context)
Definition: buffer.c:136
static void buffer_invalidate_bo_range(struct wined3d_buffer *buffer, unsigned int offset, unsigned int size)
Definition: buffer.c:56
const char * debug_d3dusage(DWORD usage)
Definition: utils.c:4217
const char * debug_glerror(GLenum error)
Definition: utils.c:4796
unsigned int GLenum
Definition: gl.h:150
#define GL_NO_ERROR
Definition: gl.h:693
#define GL_FALSE
Definition: gl.h:173
#define GL_BUFFER_SERIALIZED_MODIFY_APPLE
Definition: glext.h:4547
#define GL_BUFFER_FLUSHING_UNMAP_APPLE
Definition: glext.h:4548
#define GL_STATIC_DRAW
Definition: glext.h:350
#define GL_STREAM_DRAW_ARB
Definition: glext.h:1506
#define error(str)
Definition: mkdosfs.c:1605
#define TRACE(s)
Definition: solgame.cpp:4
BOOL supported[WINED3D_GL_EXT_COUNT]
struct opengl_funcs gl_ops
#define WINED3DUSAGE_DYNAMIC
Definition: wined3d.h:907
@ APPLE_FLUSH_BUFFER_RANGE
Definition: wined3d_gl.h:42
#define GL_EXTCALL(f)
#define checkGLcall(A)

Referenced by wined3d_buffer_prepare_location().

◆ buffer_destroy_buffer_object()

static void buffer_destroy_buffer_object ( struct wined3d_buffer buffer,
struct wined3d_context context 
)
static

Definition at line 142 of file buffer.c.

143{
144 const struct wined3d_gl_info *gl_info = context->gl_info;
145 struct wined3d_resource *resource = &buffer->resource;
146
147 if (!buffer->buffer_object)
148 return;
149
150 /* The stream source state handler might have read the memory of the
151 * vertex buffer already and got the memory in the vbo which is not
152 * valid any longer. Dirtify the stream source to force a reload. This
153 * happens only once per changed vertexbuffer and should occur rather
154 * rarely. */
155 if (resource->bind_count)
156 {
157 if (buffer->bind_flags & WINED3D_BIND_VERTEX_BUFFER)
159 if (buffer->bind_flags & WINED3D_BIND_INDEX_BUFFER)
161 if (buffer->bind_flags & WINED3D_BIND_CONSTANT_BUFFER)
162 {
169 }
170 if (buffer->bind_flags & WINED3D_BIND_STREAM_OUTPUT)
171 {
173 if (context->transform_feedback_active)
174 {
175 /* We have to make sure that transform feedback is not active
176 * when deleting a potentially bound transform feedback buffer.
177 * This may happen when the device is being destroyed. */
178 WARN("Deleting buffer object for buffer %p, disabling transform feedback.\n", buffer);
180 }
181 }
182 }
183
184 GL_EXTCALL(glDeleteBuffers(1, &buffer->buffer_object));
185 checkGLcall("glDeleteBuffers");
186 buffer->buffer_object = 0;
187
188 if (buffer->fence)
189 {
191 buffer->fence = NULL;
192 }
193 buffer->flags &= ~WINED3D_BUFFER_APPLESYNC;
194}
#define WARN(fmt,...)
Definition: precomp.h:61
void context_end_transform_feedback(struct wined3d_context *context)
Definition: context.c:4127
void device_invalidate_state(const struct wined3d_device *device, DWORD state)
Definition: device.c:5263
void wined3d_fence_destroy(struct wined3d_fence *fence)
Definition: query.c:286
#define WINED3D_BIND_VERTEX_BUFFER
Definition: wined3d.h:890
#define WINED3D_BIND_CONSTANT_BUFFER
Definition: wined3d.h:892
#define WINED3D_BIND_STREAM_OUTPUT
Definition: wined3d.h:894
#define WINED3D_BIND_INDEX_BUFFER
Definition: wined3d.h:891
#define STATE_CONSTANT_BUFFER(a)
#define STATE_STREAM_OUTPUT
#define STATE_STREAMSRC
@ WINED3D_SHADER_TYPE_HULL
@ WINED3D_SHADER_TYPE_PIXEL
@ WINED3D_SHADER_TYPE_GEOMETRY
@ WINED3D_SHADER_TYPE_DOMAIN
@ WINED3D_SHADER_TYPE_COMPUTE
@ WINED3D_SHADER_TYPE_VERTEX
#define STATE_INDEXBUFFER

Referenced by buffer_create_buffer_object(), buffer_unload(), and wined3d_buffer_destroy_object().

◆ buffer_find_decl()

static BOOL buffer_find_decl ( struct wined3d_buffer This,
const struct wined3d_stream_info si,
const struct wined3d_state state,
DWORD  fixup_flags 
)
static

Definition at line 368 of file buffer.c.

370{
371 UINT stride_this_run = 0;
372 BOOL ret = FALSE;
373
374 /* In d3d7 the vertex buffer declaration NEVER changes because it is stored in the d3d7 vertex buffer.
375 * Once we have our declaration there is no need to look it up again. Index buffers also never need
376 * conversion, so once the (empty) conversion structure is created don't bother checking again
377 */
378 if (This->flags & WINED3D_BUFFER_HASDESC)
379 {
380 if(This->resource.usage & WINED3DUSAGE_STATICDECL) return FALSE;
381 }
382
383 if (!fixup_flags)
384 {
385 TRACE("No fixup required.\n");
386 if(This->conversion_map)
387 {
388 heap_free(This->conversion_map);
389 This->conversion_map = NULL;
390 This->stride = 0;
391 return TRUE;
392 }
393
394 return FALSE;
395 }
396
397 TRACE("Finding vertex buffer conversion information\n");
398 /* Certain declaration types need some fixups before we can pass them to
399 * opengl. This means D3DCOLOR attributes with fixed function vertex
400 * processing, FLOAT4 POSITIONT with fixed function, and FLOAT16 if
401 * GL_ARB_half_float_vertex is not supported.
402 *
403 * Note for d3d8 and d3d9:
404 * The vertex buffer FVF doesn't help with finding them, we have to use
405 * the decoded vertex declaration and pick the things that concern the
406 * current buffer. A problem with this is that this can change between
407 * draws, so we have to validate the information and reprocess the buffer
408 * if it changes, and avoid false positives for performance reasons.
409 * WineD3D doesn't even know the vertex buffer any more, it is managed
410 * by the client libraries and passed to SetStreamSource and ProcessVertices
411 * as needed.
412 *
413 * We have to distinguish between vertex shaders and fixed function to
414 * pick the way we access the strided vertex information.
415 *
416 * This code sets up a per-byte array with the size of the detected
417 * stride of the arrays in the buffer. For each byte we have a field
418 * that marks the conversion needed on this byte. For example, the
419 * following declaration with fixed function vertex processing:
420 *
421 * POSITIONT, FLOAT4
422 * NORMAL, FLOAT3
423 * DIFFUSE, FLOAT16_4
424 * SPECULAR, D3DCOLOR
425 *
426 * Will result in
427 * { POSITIONT }{ NORMAL }{ DIFFUSE }{SPECULAR }
428 * [P][P][P][P][P][P][P][P][P][P][P][P][P][P][P][P][0][0][0][0][0][0][0][0][0][0][0][0][F][F][F][F][F][F][F][F][C][C][C][C]
429 *
430 * Where in this example map P means 4 component position conversion, 0
431 * means no conversion, F means FLOAT16_2 conversion and C means D3DCOLOR
432 * conversion (red / blue swizzle).
433 *
434 * If we're doing conversion and the stride changes we have to reconvert
435 * the whole buffer. Note that we do not mind if the semantic changes,
436 * we only care for the conversion type. So if the NORMAL is replaced
437 * with a TEXCOORD, nothing has to be done, or if the DIFFUSE is replaced
438 * with a D3DCOLOR BLENDWEIGHT we can happily dismiss the change. Some
439 * conversion types depend on the semantic as well, for example a FLOAT4
440 * texcoord needs no conversion while a FLOAT4 positiont needs one
441 */
442
444 fixup_flags, &stride_this_run) || ret;
445 fixup_flags &= ~WINED3D_BUFFER_FIXUP_XYZRHW;
446
448 fixup_flags, &stride_this_run) || ret;
450 fixup_flags, &stride_this_run) || ret;
452 fixup_flags, &stride_this_run) || ret;
454 fixup_flags, &stride_this_run) || ret;
456 fixup_flags, &stride_this_run) || ret;
458 fixup_flags, &stride_this_run) || ret;
460 fixup_flags, &stride_this_run) || ret;
462 fixup_flags, &stride_this_run) || ret;
464 fixup_flags, &stride_this_run) || ret;
466 fixup_flags, &stride_this_run) || ret;
468 fixup_flags, &stride_this_run) || ret;
470 fixup_flags, &stride_this_run) || ret;
472 fixup_flags, &stride_this_run) || ret;
473
474 if (!stride_this_run && This->conversion_map)
475 {
476 /* Sanity test */
477 if (!ret)
478 ERR("no converted attributes found, old conversion map exists, and no declaration change?\n");
479 heap_free(This->conversion_map);
480 This->conversion_map = NULL;
481 This->stride = 0;
482 }
483
484 if (ret) TRACE("Conversion information changed\n");
485
486 return ret;
487}
static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct wined3d_stream_info *si, const struct wined3d_state *state, UINT attrib_idx, DWORD fixup_flags, DWORD *stride_this_run)
Definition: buffer.c:330
#define WINED3D_BUFFER_HASDESC
Definition: buffer.c:32
unsigned int UINT
Definition: ndis.h:50
#define WINED3DUSAGE_STATICDECL
Definition: wined3d.h:920
@ WINED3D_FFP_TEXCOORD4
@ WINED3D_FFP_TEXCOORD3
@ WINED3D_FFP_SPECULAR
@ WINED3D_FFP_TEXCOORD7
@ WINED3D_FFP_TEXCOORD1
@ WINED3D_FFP_POSITION
@ WINED3D_FFP_NORMAL
@ WINED3D_FFP_TEXCOORD5
@ WINED3D_FFP_BLENDWEIGHT
@ WINED3D_FFP_TEXCOORD2
@ WINED3D_FFP_DIFFUSE
@ WINED3D_FFP_TEXCOORD6
@ WINED3D_FFP_BLENDINDICES
@ WINED3D_FFP_TEXCOORD0

Referenced by wined3d_buffer_load().

◆ buffer_init()

static HRESULT buffer_init ( struct wined3d_buffer buffer,
struct wined3d_device device,
UINT  size,
DWORD  usage,
enum wined3d_format_id  format_id,
unsigned int  access,
unsigned int  bind_flags,
const struct wined3d_sub_resource_data data,
void parent,
const struct wined3d_parent_ops parent_ops 
)
static

Definition at line 1346 of file buffer.c.

1349{
1350 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
1351 const struct wined3d_format *format = wined3d_get_format(gl_info, format_id, usage);
1352 BOOL dynamic_buffer_ok;
1353 HRESULT hr;
1354
1355 if (!size)
1356 {
1357 WARN("Size 0 requested, returning E_INVALIDARG.\n");
1358 return E_INVALIDARG;
1359 }
1360
1362 {
1363 WARN("Size %#x is not suitably aligned for constant buffers.\n", size);
1364 return E_INVALIDARG;
1365 }
1366
1367 if (data && !data->data)
1368 {
1369 WARN("Invalid sub-resource data specified.\n");
1370 return E_INVALIDARG;
1371 }
1372
1374 0, usage, access, size, 1, 1, size, parent, parent_ops, &buffer_resource_ops)))
1375 {
1376 WARN("Failed to initialize resource, hr %#x.\n", hr);
1377 return hr;
1378 }
1379 buffer->buffer_type_hint = buffer_type_hint_from_bind_flags(gl_info, bind_flags);
1380 buffer->bind_flags = bind_flags;
1381 buffer->locations = WINED3D_LOCATION_SYSMEM;
1382
1383 TRACE("buffer %p, size %#x, usage %#x, format %s, memory @ %p.\n",
1384 buffer, buffer->resource.size, buffer->resource.usage,
1385 debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory);
1386
1387 if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING
1389 {
1390 /* SWvp and managed buffers always return the same pointer in buffer
1391 * maps and retain data in DISCARD maps. Keep a system memory copy of
1392 * the buffer to provide the same behavior to the application. */
1393 TRACE("Using doublebuffer mode.\n");
1395 }
1396
1397 /* Observations show that draw_primitive_immediate_mode() is faster on
1398 * dynamic vertex buffers than converting + draw_primitive_arrays().
1399 * (Half-Life 2 and others.) */
1400 dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] || gl_info->supported[ARB_MAP_BUFFER_RANGE];
1401
1402 if (!gl_info->supported[ARB_VERTEX_BUFFER_OBJECT])
1403 {
1404 TRACE("Not creating a BO because GL_ARB_vertex_buffer is not supported.\n");
1405 }
1406 else if (!(access & WINED3D_RESOURCE_ACCESS_GPU))
1407 {
1408 TRACE("Not creating a BO because the buffer is not GPU accessible.\n");
1409 }
1410 else if (!dynamic_buffer_ok && (buffer->resource.usage & WINED3DUSAGE_DYNAMIC))
1411 {
1412 TRACE("Not creating a BO because the buffer has dynamic usage and no GL support.\n");
1413 }
1414 else
1415 {
1416 buffer->flags |= WINED3D_BUFFER_USE_BO;
1417 }
1418
1419 if (!(buffer->maps = heap_alloc(sizeof(*buffer->maps))))
1420 {
1421 ERR("Out of memory.\n");
1422 buffer_unload(&buffer->resource);
1423 resource_cleanup(&buffer->resource);
1425 return E_OUTOFMEMORY;
1426 }
1427 buffer->maps_size = 1;
1428
1429 if (data)
1431 0, NULL, data->data, data->row_pitch, data->slice_pitch);
1432
1433 return WINED3D_OK;
1434}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
static const struct wined3d_resource_ops buffer_resource_ops
Definition: buffer.c:1313
static void buffer_unload(struct wined3d_resource *resource)
Definition: buffer.c:738
#define WINED3D_BUFFER_USE_BO
Definition: buffer.c:33
static GLenum buffer_type_hint_from_bind_flags(const struct wined3d_gl_info *gl_info, unsigned int bind_flags)
Definition: buffer.c:1324
void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, unsigned int depth_pitch)
Definition: device.c:4281
HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device, enum wined3d_resource_type type, const struct wined3d_format *format, enum wined3d_multisample_type multisample_type, unsigned int multisample_quality, unsigned int usage, unsigned int access, unsigned int width, unsigned int height, unsigned int depth, unsigned int size, void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops)
Definition: resource.c:59
void resource_cleanup(struct wined3d_resource *resource)
Definition: resource.c:237
const struct wined3d_format * wined3d_get_format(const struct wined3d_gl_info *gl_info, enum wined3d_format_id format_id, unsigned int resource_usage)
Definition: utils.c:3831
r parent
Definition: btrfs.c:3010
GLsizeiptr size
Definition: glext.h:5919
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
#define FAILED(hr)
Definition: intsafe.h:51
static UINT format_id
Definition: clipboard.c:1343
HRESULT hr
Definition: shlfolder.c:183
Definition: devices.h:37
@ WINED3D_MULTISAMPLE_NONE
Definition: wined3d.h:554
#define WINED3D_OK
Definition: wined3d.h:37
#define WINED3D_RESOURCE_ACCESS_GPU
Definition: wined3d.h:55
@ WINED3D_RTYPE_BUFFER
Definition: wined3d.h:698
#define WINED3DCREATE_SOFTWARE_VERTEXPROCESSING
Definition: wined3d.h:1011
@ ARB_VERTEX_BUFFER_OBJECT
Definition: wined3d_gl.h:138
@ ARB_MAP_BUFFER_RANGE
Definition: wined3d_gl.h:83
#define WINED3D_CONSTANT_BUFFER_ALIGNMENT
static BOOL wined3d_resource_access_is_managed(unsigned int access)
static void wined3d_resource_wait_idle(struct wined3d_resource *resource)

◆ buffer_invalidate_bo_range()

static void buffer_invalidate_bo_range ( struct wined3d_buffer buffer,
unsigned int  offset,
unsigned int  size 
)
static

Definition at line 56 of file buffer.c.

57{
58 if (!offset && (!size || size == buffer->resource.size))
59 goto invalidate_all;
60
61 if (offset > buffer->resource.size || size > buffer->resource.size - offset)
62 {
63 WARN("Invalid range specified, invalidating entire buffer.\n");
64 goto invalidate_all;
65 }
66
67 if (!wined3d_array_reserve((void **)&buffer->maps, &buffer->maps_size,
68 buffer->modified_areas + 1, sizeof(*buffer->maps)))
69 {
70 ERR("Failed to allocate maps array, invalidating entire buffer.\n");
71 goto invalidate_all;
72 }
73
74 buffer->maps[buffer->modified_areas].offset = offset;
75 buffer->maps[buffer->modified_areas].size = size;
76 ++buffer->modified_areas;
77 return;
78
79invalidate_all:
80 buffer->modified_areas = 1;
81 buffer->maps[0].offset = 0;
82 buffer->maps[0].size = buffer->resource.size;
83}
BOOL wined3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size)
Definition: utils.c:6526
GLintptr offset
Definition: glext.h:5920

Referenced by buffer_create_buffer_object(), wined3d_buffer_invalidate_range(), wined3d_buffer_load(), and wined3d_buffer_map().

◆ buffer_is_dirty()

static BOOL buffer_is_dirty ( const struct wined3d_buffer buffer)
static

Definition at line 90 of file buffer.c.

91{
92 return !!buffer->modified_areas;
93}

Referenced by wined3d_buffer_load().

◆ buffer_is_fully_dirty()

static BOOL buffer_is_fully_dirty ( const struct wined3d_buffer buffer)
static

Definition at line 95 of file buffer.c.

96{
97 return buffer->modified_areas == 1
98 && !buffer->maps->offset && buffer->maps->size == buffer->resource.size;
99}

Referenced by wined3d_buffer_load().

◆ buffer_mark_used()

static void buffer_mark_used ( struct wined3d_buffer buffer)
static

Definition at line 881 of file buffer.c.

882{
883 buffer->flags &= ~WINED3D_BUFFER_DISCARD;
884}

Referenced by wined3d_buffer_copy(), and wined3d_buffer_load().

◆ buffer_process_converted_attribute()

static BOOL buffer_process_converted_attribute ( struct wined3d_buffer buffer,
const enum wined3d_buffer_conversion_type  conversion_type,
const struct wined3d_stream_info_element attrib,
DWORD stride_this_run 
)
static

Definition at line 272 of file buffer.c.

275{
276 const struct wined3d_format *format = attrib->format;
277 BOOL ret = FALSE;
278 unsigned int i;
280
281 /* Check for some valid situations which cause us pain. One is if the buffer is used for
282 * constant attributes(stride = 0), the other one is if the buffer is used on two streams
283 * with different strides. In the 2nd case we might have to drop conversion entirely,
284 * it is possible that the same bytes are once read as FLOAT2 and once as UBYTE4N.
285 */
286 if (!attrib->stride)
287 {
288 FIXME("%s used with stride 0, let's hope we get the vertex stride from somewhere else.\n",
290 }
291 else if (attrib->stride != *stride_this_run && *stride_this_run)
292 {
293 FIXME("Got two concurrent strides, %d and %d.\n", attrib->stride, *stride_this_run);
294 }
295 else
296 {
297 *stride_this_run = attrib->stride;
298 if (buffer->stride != *stride_this_run)
299 {
300 /* We rely that this happens only on the first converted attribute that is found,
301 * if at all. See above check
302 */
303 TRACE("Reconverting because converted attributes occur, and the stride changed.\n");
304 buffer->stride = *stride_this_run;
305 heap_free(buffer->conversion_map);
306 buffer->conversion_map = heap_calloc(buffer->stride, sizeof(*buffer->conversion_map));
307 ret = TRUE;
308 }
309 }
310
311 data = ((DWORD_PTR)attrib->data.addr) % buffer->stride;
312 for (i = 0; i < format->attribute_size; ++i)
313 {
314 DWORD_PTR idx = (data + i) % buffer->stride;
315 if (buffer->conversion_map[idx] != conversion_type)
316 {
317 TRACE("Byte %lu in vertex changed:\n", idx);
318 TRACE(" It was type %#x, is %#x now.\n", buffer->conversion_map[idx], conversion_type);
319 ret = TRUE;
320 buffer->conversion_map[idx] = conversion_type;
321 }
322 }
323
324 return ret;
325}
unsigned int idx
Definition: utils.c:41
if(dx< 0)
Definition: linetemp.h:194
static void * heap_calloc(SIZE_T count, SIZE_T size)
Definition: heap.h:49
struct wined3d_bo_address data
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65

Referenced by buffer_check_attribute().

◆ buffer_resource_decref()

static ULONG buffer_resource_decref ( struct wined3d_resource resource)
static

Definition at line 1243 of file buffer.c.

1244{
1246}
ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer)
Definition: buffer.c:791
static struct wined3d_buffer * buffer_from_resource(struct wined3d_resource *resource)

◆ buffer_resource_incref()

static ULONG buffer_resource_incref ( struct wined3d_resource resource)
static

Definition at line 1238 of file buffer.c.

1239{
1241}
ULONG CDECL wined3d_buffer_incref(struct wined3d_buffer *buffer)
Definition: buffer.c:525

◆ buffer_resource_preload()

static void buffer_resource_preload ( struct wined3d_resource resource)
static

Definition at line 1248 of file buffer.c.

1249{
1250 struct wined3d_context *context;
1251
1252 context = context_acquire(resource->device, NULL, 0);
1255}
void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_state *state)
Definition: buffer.c:887
struct wined3d_context * context_acquire(const struct wined3d_device *device, struct wined3d_texture *texture, unsigned int sub_resource_idx)
Definition: context.c:4242
void context_release(struct wined3d_context *context)
Definition: context.c:1571

◆ buffer_resource_sub_resource_map()

static HRESULT buffer_resource_sub_resource_map ( struct wined3d_resource resource,
unsigned int  sub_resource_idx,
struct wined3d_map_desc map_desc,
const struct wined3d_box box,
DWORD  flags 
)
static

Definition at line 1257 of file buffer.c.

1259{
1261 UINT offset, size;
1262
1263 if (sub_resource_idx)
1264 {
1265 WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
1266 return E_INVALIDARG;
1267 }
1268
1269 if (box)
1270 {
1271 offset = box->left;
1272 size = box->right - box->left;
1273 }
1274 else
1275 {
1276 offset = size = 0;
1277 }
1278
1279 map_desc->row_pitch = map_desc->slice_pitch = buffer->desc.byte_width;
1280 return wined3d_buffer_map(buffer, offset, size, (BYTE **)&map_desc->data, flags);
1281}
static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UINT size, BYTE **data, DWORD flags)
Definition: buffer.c:1002
GLbitfield flags
Definition: glext.h:7161
Definition: palette.c:468

◆ buffer_resource_sub_resource_map_info()

static HRESULT buffer_resource_sub_resource_map_info ( struct wined3d_resource resource,
unsigned int  sub_resource_idx,
struct wined3d_map_info info,
DWORD  flags 
)
static

Definition at line 1283 of file buffer.c.

1285{
1287
1288 if (sub_resource_idx)
1289 {
1290 WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
1291 return E_INVALIDARG;
1292 }
1293
1294 info->row_pitch = buffer->desc.byte_width;
1295 info->slice_pitch = buffer->desc.byte_width;
1296 info->size = buffer->resource.size;
1297
1298 return WINED3D_OK;
1299}

◆ buffer_resource_sub_resource_unmap()

static HRESULT buffer_resource_sub_resource_unmap ( struct wined3d_resource resource,
unsigned int  sub_resource_idx 
)
static

Definition at line 1301 of file buffer.c.

1302{
1303 if (sub_resource_idx)
1304 {
1305 WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
1306 return E_INVALIDARG;
1307 }
1308
1310 return WINED3D_OK;
1311}
static void wined3d_buffer_unmap(struct wined3d_buffer *buffer)
Definition: buffer.c:1132

◆ buffer_sync_apple()

static void buffer_sync_apple ( struct wined3d_buffer buffer,
DWORD  flags,
const struct wined3d_gl_info gl_info 
)
static

Definition at line 815 of file buffer.c.

816{
818 HRESULT hr;
819
820 /* No fencing needs to be done if the app promises not to overwrite
821 * existing data. */
823 return;
824
826 {
827 GL_EXTCALL(glBufferData(buffer->buffer_type_hint, buffer->resource.size, NULL, buffer->buffer_object_usage));
828 checkGLcall("glBufferData");
829 return;
830 }
831
832 if (!buffer->fence)
833 {
834 TRACE("Creating fence for buffer %p.\n", buffer);
835
836 if (FAILED(hr = wined3d_fence_create(buffer->resource.device, &buffer->fence)))
837 {
839 FIXME("Fences not supported, dropping async buffer locks.\n");
840 else
841 ERR("Failed to create fence, hr %#x.\n", hr);
842 goto drop_fence;
843 }
844
845 /* Since we don't know about old draws a glFinish is needed once */
846 gl_info->gl_ops.gl.p_glFinish();
847 return;
848 }
849
850 TRACE("Synchronizing buffer %p.\n", buffer);
851 ret = wined3d_fence_wait(buffer->fence, buffer->resource.device);
852 switch (ret)
853 {
855 case WINED3D_FENCE_OK:
856 /* All done */
857 return;
858
860 WARN("Cannot synchronize buffer lock due to a thread conflict.\n");
861 goto drop_fence;
862
863 default:
864 ERR("wined3d_fence_wait() returned %u, dropping async buffer locks.\n", ret);
865 goto drop_fence;
866 }
867
868drop_fence:
869 if (buffer->fence)
870 {
872 buffer->fence = NULL;
873 }
874
875 gl_info->gl_ops.gl.p_glFinish();
876 GL_EXTCALL(glBufferParameteriAPPLE(buffer->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE));
877 checkGLcall("glBufferParameteriAPPLE(buffer->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)");
878 buffer->flags &= ~WINED3D_BUFFER_APPLESYNC;
879}
enum wined3d_fence_result wined3d_fence_wait(const struct wined3d_fence *fence, const struct wined3d_device *device)
Definition: query.c:169
HRESULT wined3d_fence_create(struct wined3d_device *device, struct wined3d_fence **fence)
Definition: query.c:303
#define GL_TRUE
Definition: gl.h:174
#define WINED3DERR_NOTAVAILABLE
Definition: wined3d.h:46
#define WINED3D_MAP_DISCARD
Definition: wined3d.h:935
#define WINED3D_MAP_NOOVERWRITE
Definition: wined3d.h:934
wined3d_fence_result
@ WINED3D_FENCE_WRONG_THREAD
@ WINED3D_FENCE_OK
@ WINED3D_FENCE_NOT_STARTED

Referenced by wined3d_buffer_map().

◆ buffer_type_hint_from_bind_flags()

static GLenum buffer_type_hint_from_bind_flags ( const struct wined3d_gl_info gl_info,
unsigned int  bind_flags 
)
static

Definition at line 1324 of file buffer.c.

1326{
1327 if (bind_flags == WINED3D_BIND_INDEX_BUFFER)
1329
1332 return GL_TEXTURE_BUFFER;
1333
1334 if (bind_flags & WINED3D_BIND_CONSTANT_BUFFER)
1335 return GL_UNIFORM_BUFFER;
1336
1337 if (bind_flags & WINED3D_BIND_STREAM_OUTPUT)
1339
1341 FIXME("Unhandled bind flags %#x.\n", bind_flags);
1342
1343 return GL_ARRAY_BUFFER;
1344}
#define GL_UNIFORM_BUFFER
Definition: glext.h:1846
#define GL_ARRAY_BUFFER
Definition: glext.h:336
#define GL_TEXTURE_BUFFER
Definition: glext.h:748
#define GL_TRANSFORM_FEEDBACK_BUFFER
Definition: glext.h:557
#define GL_ELEMENT_ARRAY_BUFFER
Definition: glext.h:337
#define WINED3D_BIND_UNORDERED_ACCESS
Definition: wined3d.h:897
#define WINED3D_BIND_SHADER_RESOURCE
Definition: wined3d.h:893
@ ARB_TEXTURE_BUFFER_OBJECT
Definition: wined3d_gl.h:108

Referenced by buffer_init().

◆ buffer_unload()

static void buffer_unload ( struct wined3d_resource resource)
static

Definition at line 738 of file buffer.c.

739{
741
742 TRACE("buffer %p.\n", buffer);
743
744 if (buffer->buffer_object)
745 {
746 struct wined3d_context *context;
747
748 context = context_acquire(resource->device, NULL, 0);
749
754
756
757 heap_free(buffer->conversion_map);
758 buffer->conversion_map = NULL;
759 buffer->stride = 0;
760 buffer->conversion_stride = 0;
761 buffer->flags &= ~WINED3D_BUFFER_HASDESC;
762 }
763
765}
void wined3d_buffer_invalidate_location(struct wined3d_buffer *buffer, DWORD location)
Definition: buffer.c:130
void resource_unload(struct wined3d_resource *resource)
Definition: resource.c:257
#define WINED3D_LOCATION_BUFFER

Referenced by buffer_init(), and wined3d_buffer_drop_bo().

◆ fixup_d3dcolor()

static unsigned int fixup_d3dcolor ( DWORD dst_color)
inlinestatic

Definition at line 489 of file buffer.c.

490{
491 DWORD src_color = *dst_color;
492
493 /* Color conversion like in draw_primitive_immediate_mode(). Watch out for
494 * endianness. If we want this to work on big-endian machines as well we
495 * have to consider more things.
496 *
497 * 0xff000000: Alpha mask
498 * 0x00ff0000: Blue mask
499 * 0x0000ff00: Green mask
500 * 0x000000ff: Red mask
501 */
502 *dst_color = 0;
503 *dst_color |= (src_color & 0xff00ff00u); /* Alpha Green */
504 *dst_color |= (src_color & 0x00ff0000u) >> 16; /* Red */
505 *dst_color |= (src_color & 0x000000ffu) << 16; /* Blue */
506
507 return sizeof(*dst_color);
508}

Referenced by buffer_conversion_upload().

◆ fixup_transformed_pos()

static unsigned int fixup_transformed_pos ( struct wined3d_vec4 p)
inlinestatic

Definition at line 510 of file buffer.c.

511{
512 /* rhw conversion like in position_float4(). */
513 if (p->w != 1.0f && p->w != 0.0f)
514 {
515 float w = 1.0f / p->w;
516 p->x *= w;
517 p->y *= w;
518 p->z *= w;
519 p->w = w;
520 }
521
522 return sizeof(*p);
523}
GLfloat GLfloat p
Definition: glext.h:8902
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102

Referenced by buffer_conversion_upload().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( d3d  )

◆ wined3d_buffer_copy()

void wined3d_buffer_copy ( struct wined3d_buffer dst_buffer,
unsigned int  dst_offset,
struct wined3d_buffer src_buffer,
unsigned int  src_offset,
unsigned int  size 
)

Definition at line 1195 of file buffer.c.

1197{
1198 struct wined3d_bo_address dst, src;
1199 struct wined3d_context *context;
1200 DWORD dst_location;
1201
1202 buffer_mark_used(dst_buffer);
1203 buffer_mark_used(src_buffer);
1204
1205 dst_location = wined3d_buffer_get_memory(dst_buffer, &dst, dst_buffer->locations);
1206 dst.addr += dst_offset;
1207
1208 wined3d_buffer_get_memory(src_buffer, &src, src_buffer->locations);
1209 src.addr += src_offset;
1210
1211 context = context_acquire(dst_buffer->resource.device, NULL, 0);
1213 &src, src_buffer->buffer_type_hint, size);
1215
1216 wined3d_buffer_invalidate_range(dst_buffer, ~dst_location, dst_offset, size);
1217}
DWORD wined3d_buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_bo_address *data, DWORD locations)
Definition: buffer.c:713
static void wined3d_buffer_invalidate_range(struct wined3d_buffer *buffer, DWORD location, unsigned int offset, unsigned int size)
Definition: buffer.c:113
static void buffer_mark_used(struct wined3d_buffer *buffer)
Definition: buffer.c:881
void context_copy_bo_address(struct wined3d_context *context, const struct wined3d_bo_address *dst, GLenum dst_binding, const struct wined3d_bo_address *src, GLenum src_binding, size_t size)
Definition: context.c:2846
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
struct wined3d_resource resource

Referenced by wined3d_cs_exec_blt_sub_resource().

◆ wined3d_buffer_create()

HRESULT CDECL wined3d_buffer_create ( struct wined3d_device device,
const struct wined3d_buffer_desc desc,
const struct wined3d_sub_resource_data data,
void parent,
const struct wined3d_parent_ops parent_ops,
struct wined3d_buffer **  buffer 
)

Definition at line 1436 of file buffer.c.

1439{
1440 struct wined3d_buffer *object;
1441 HRESULT hr;
1442
1443 TRACE("device %p, desc %p, data %p, parent %p, parent_ops %p, buffer %p.\n",
1444 device, desc, data, parent, parent_ops, buffer);
1445
1446 if (!(object = heap_alloc_zero(sizeof(*object))))
1447 return E_OUTOFMEMORY;
1448
1449 if (FAILED(hr = buffer_init(object, device, desc->byte_width, desc->usage, WINED3DFMT_UNKNOWN,
1450 desc->access, desc->bind_flags, data, parent, parent_ops)))
1451 {
1452 WARN("Failed to initialize buffer, hr %#x.\n", hr);
1453 heap_free(object);
1454 return hr;
1455 }
1456 object->desc = *desc;
1457
1458 TRACE("Created buffer %p.\n", object);
1459
1460 *buffer = object;
1461
1462 return WINED3D_OK;
1463}
#define buffer_init
Definition: intsym.h:261
static const WCHAR desc[]
Definition: protectdata.c:36
@ WINED3DFMT_UNKNOWN
Definition: wined3d.h:107

Referenced by d3d8_device_prepare_index_buffer(), d3d8_device_prepare_vertex_buffer(), d3d9_device_prepare_index_buffer(), d3d9_device_prepare_vertex_buffer(), d3d_device_prepare_index_buffer(), d3d_device_prepare_vertex_buffer(), d3d_execute_buffer_SetExecuteData(), d3d_vertex_buffer_create_wined3d_buffer(), indexbuffer_init(), and vertexbuffer_init().

◆ wined3d_buffer_decref()

ULONG CDECL wined3d_buffer_decref ( struct wined3d_buffer buffer)

Definition at line 791 of file buffer.c.

792{
793 ULONG refcount = InterlockedDecrement(&buffer->resource.ref);
794
795 TRACE("%p decreasing refcount to %u.\n", buffer, refcount);
796
797 if (!refcount)
798 {
799 buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent);
800 resource_cleanup(&buffer->resource);
802 }
803
804 return refcount;
805}
#define InterlockedDecrement
Definition: armddk.h:52
void wined3d_cs_destroy_object(struct wined3d_cs *cs, void(*callback)(void *object), void *object)
Definition: cs.c:1885
static void wined3d_buffer_destroy_object(void *object)
Definition: buffer.c:773
uint32_t ULONG
Definition: typedefs.h:59

Referenced by buffer_resource_decref(), d3d8_device_prepare_index_buffer(), d3d8_device_prepare_vertex_buffer(), d3d8_device_Release(), d3d8_device_Reset(), d3d8_indexbuffer_Release(), d3d8_vertexbuffer_Release(), d3d9_device_prepare_index_buffer(), d3d9_device_prepare_vertex_buffer(), d3d9_device_Release(), d3d9_device_reset(), d3d9_indexbuffer_Release(), d3d9_vertexbuffer_Release(), d3d_device_inner_Release(), d3d_device_prepare_index_buffer(), d3d_device_prepare_vertex_buffer(), d3d_execute_buffer_Release(), d3d_execute_buffer_SetExecuteData(), d3d_vertex_buffer7_Lock(), d3d_vertex_buffer7_Release(), d3d_vertex_buffer_create(), state_unbind_resources(), wined3d_device_set_constant_buffer(), wined3d_device_set_index_buffer(), wined3d_device_set_stream_output(), wined3d_device_set_stream_source(), and wined3d_stateblock_capture().

◆ wined3d_buffer_destroy_object()

static void wined3d_buffer_destroy_object ( void object)
static

Definition at line 773 of file buffer.c.

774{
775 struct wined3d_buffer *buffer = object;
776 struct wined3d_context *context;
777
778 if (buffer->buffer_object)
779 {
780 context = context_acquire(buffer->resource.device, NULL, 0);
783
784 heap_free(buffer->conversion_map);
785 }
786
787 heap_free(buffer->maps);
789}

Referenced by wined3d_buffer_decref().

◆ wined3d_buffer_drop_bo()

static void wined3d_buffer_drop_bo ( struct wined3d_buffer buffer)
static

Definition at line 767 of file buffer.c.

768{
769 buffer->flags &= ~WINED3D_BUFFER_USE_BO;
770 buffer_unload(&buffer->resource);
771}

Referenced by wined3d_buffer_load(), and wined3d_buffer_map().

◆ wined3d_buffer_evict_sysmem()

static void wined3d_buffer_evict_sysmem ( struct wined3d_buffer buffer)
static

Definition at line 43 of file buffer.c.

44{
46 {
47 TRACE("Not evicting system memory for buffer %p.\n", buffer);
48 return;
49 }
50
51 TRACE("Evicting system memory for buffer %p.\n", buffer);
54}
void wined3d_resource_free_sysmem(struct wined3d_resource *resource)
Definition: resource.c:504

Referenced by wined3d_buffer_load_location(), and wined3d_buffer_map().

◆ wined3d_buffer_get_memory()

DWORD wined3d_buffer_get_memory ( struct wined3d_buffer buffer,
struct wined3d_bo_address data,
DWORD  locations 
)

Definition at line 713 of file buffer.c.

715{
716 TRACE("buffer %p, data %p, locations %s.\n",
718
720 {
721 data->buffer_object = buffer->buffer_object;
722 data->addr = NULL;
724 }
726 {
727 data->buffer_object = 0;
728 data->addr = buffer->resource.heap_memory;
730 }
731
732 ERR("Unexpected locations %s.\n", wined3d_debug_location(locations));
733 data->buffer_object = 0;
734 data->addr = NULL;
735 return 0;
736}
const char * wined3d_debug_location(DWORD location)
Definition: utils.c:6396
GLsizei const GLint * locations
Definition: glext.h:10542

Referenced by context_update_stream_info(), wined3d_buffer_copy(), and wined3d_unordered_access_view_copy_counter().

◆ wined3d_buffer_get_parent()

void *CDECL wined3d_buffer_get_parent ( const struct wined3d_buffer buffer)

Definition at line 807 of file buffer.c.

808{
809 TRACE("buffer %p.\n", buffer);
810
811 return buffer->resource.parent;
812}

Referenced by d3d8_device_GetIndices(), d3d8_device_GetStreamSource(), d3d9_device_GetIndices(), d3d9_device_GetStreamSource(), and wined3d_rendertarget_view_get_sub_resource_parent().

◆ wined3d_buffer_get_resource()

◆ wined3d_buffer_incref()

ULONG CDECL wined3d_buffer_incref ( struct wined3d_buffer buffer)

◆ wined3d_buffer_invalidate_location()

◆ wined3d_buffer_invalidate_range()

static void wined3d_buffer_invalidate_range ( struct wined3d_buffer buffer,
DWORD  location,
unsigned int  offset,
unsigned int  size 
)
static

Definition at line 113 of file buffer.c.

115{
116 TRACE("buffer %p, location %s, offset %u, size %u.\n",
118
121
122 buffer->locations &= ~location;
123
124 TRACE("New locations flags are %s.\n", wined3d_debug_location(buffer->locations));
125
126 if (!buffer->locations)
127 ERR("Buffer %p does not have any up to date location.\n", buffer);
128}

Referenced by wined3d_buffer_copy(), wined3d_buffer_invalidate_location(), and wined3d_buffer_map().

◆ wined3d_buffer_load()

void wined3d_buffer_load ( struct wined3d_buffer buffer,
struct wined3d_context context,
const struct wined3d_state state 
)

Definition at line 887 of file buffer.c.

889{
890 const struct wined3d_gl_info *gl_info = context->gl_info;
891 BOOL decl_changed = FALSE;
892
893 TRACE("buffer %p.\n", buffer);
894
895 if (buffer->resource.map_count)
896 {
897 WARN("Buffer is mapped, skipping preload.\n");
898 return;
899 }
900
902
903 /* TODO: Make converting independent from VBOs */
904 if (!(buffer->flags & WINED3D_BUFFER_USE_BO))
905 {
906 /* Not doing any conversion */
907 return;
908 }
909
911 {
912 ERR("Failed to prepare buffer location.\n");
913 return;
914 }
915
916 /* Reading the declaration makes only sense if we have valid state information
917 * (i.e., if this function is called during draws). */
918 if (state)
919 {
920 DWORD fixup_flags = 0;
921
922 if (!use_vs(state))
923 {
924 if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && !context->d3d_info->ffp_generic_attributes)
925 fixup_flags |= WINED3D_BUFFER_FIXUP_D3DCOLOR;
926 if (!context->d3d_info->xyzrhw)
927 fixup_flags |= WINED3D_BUFFER_FIXUP_XYZRHW;
928 }
929
930 decl_changed = buffer_find_decl(buffer, &context->stream_info, state, fixup_flags);
932 }
933
934 if (!decl_changed && !(buffer->flags & WINED3D_BUFFER_HASDESC && buffer_is_dirty(buffer)))
935 {
936 ++buffer->draw_count;
937 if (buffer->draw_count > VB_RESETDECLCHANGE)
938 buffer->decl_change_count = 0;
939 if (buffer->draw_count > VB_RESETFULLCONVS)
940 buffer->full_conversion_count = 0;
941 return;
942 }
943
944 /* If applications change the declaration over and over, reconverting all the time is a huge
945 * performance hit. So count the declaration changes and release the VBO if there are too many
946 * of them (and thus stop converting)
947 */
948 if (decl_changed)
949 {
950 ++buffer->decl_change_count;
951 buffer->draw_count = 0;
952
953 if (buffer->decl_change_count > VB_MAXDECLCHANGES
954 || (buffer->conversion_map && (buffer->resource.usage & WINED3DUSAGE_DYNAMIC)))
955 {
956 FIXME("Too many declaration changes or converting dynamic buffer, stopping converting.\n");
958 return;
959 }
960
961 /* The declaration changed, reload the whole buffer. */
962 WARN("Reloading buffer because of a vertex declaration change.\n");
964 }
965 else
966 {
967 /* However, it is perfectly fine to change the declaration every now and then. We don't want a game that
968 * changes it every minute drop the VBO after VB_MAX_DECL_CHANGES minutes. So count draws without
969 * decl changes and reset the decl change count after a specific number of them
970 */
971 if (buffer->conversion_map && buffer_is_fully_dirty(buffer))
972 {
973 ++buffer->full_conversion_count;
974 if (buffer->full_conversion_count > VB_MAXFULLCONVERSIONS)
975 {
976 FIXME("Too many full buffer conversions, stopping converting.\n");
978 return;
979 }
980 }
981 else
982 {
983 ++buffer->draw_count;
984 if (buffer->draw_count > VB_RESETDECLCHANGE)
985 buffer->decl_change_count = 0;
986 if (buffer->draw_count > VB_RESETFULLCONVS)
987 buffer->full_conversion_count = 0;
988 }
989 }
990
992 ERR("Failed to load buffer location.\n");
993}
static BOOL buffer_is_fully_dirty(const struct wined3d_buffer *buffer)
Definition: buffer.c:95
static BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer, struct wined3d_context *context, DWORD location)
Definition: buffer.c:608
static BOOL buffer_is_dirty(const struct wined3d_buffer *buffer)
Definition: buffer.c:90
#define VB_RESETFULLCONVS
Definition: buffer.c:41
static void wined3d_buffer_drop_bo(struct wined3d_buffer *buffer)
Definition: buffer.c:767
#define VB_MAXFULLCONVERSIONS
Definition: buffer.c:40
#define VB_RESETDECLCHANGE
Definition: buffer.c:39
static BOOL buffer_find_decl(struct wined3d_buffer *This, const struct wined3d_stream_info *si, const struct wined3d_state *state, DWORD fixup_flags)
Definition: buffer.c:368
#define VB_MAXDECLCHANGES
Definition: buffer.c:38
@ ARB_VERTEX_ARRAY_BGRA
Definition: wined3d_gl.h:136
static BOOL use_vs(const struct wined3d_state *state)

Referenced by buffer_resource_preload(), context_apply_draw_state(), context_load_shader_resources(), context_load_stream_output_buffers(), context_update_stream_info(), dispatch_compute(), and draw_primitive().

◆ wined3d_buffer_load_location()

BOOL wined3d_buffer_load_location ( struct wined3d_buffer buffer,
struct wined3d_context context,
DWORD  location 
)

Definition at line 641 of file buffer.c.

643{
644 const struct wined3d_gl_info *gl_info = context->gl_info;
645
646 TRACE("buffer %p, context %p, location %s.\n",
648
649 if (buffer->locations & location)
650 {
651 TRACE("Location (%#x) is already up to date.\n", location);
652 return TRUE;
653 }
654
655 if (!buffer->locations)
656 {
657 ERR("Buffer %p does not have any up to date location.\n", buffer);
660 }
661
662 TRACE("Current buffer location %s.\n", wined3d_debug_location(buffer->locations));
663
665 return FALSE;
666
667 if (buffer->locations & WINED3D_LOCATION_DISCARDED)
668 {
669 TRACE("Buffer previously discarded, nothing to do.\n");
672 return TRUE;
673 }
674
675 switch (location)
676 {
679 GL_EXTCALL(glGetBufferSubData(buffer->buffer_type_hint, 0, buffer->resource.size,
680 buffer->resource.heap_memory));
681 checkGLcall("buffer download");
682 break;
683
685 if (!buffer->conversion_map)
686 wined3d_buffer_upload_ranges(buffer, context, buffer->resource.heap_memory,
687 0, buffer->modified_areas, buffer->maps);
688 else
690 break;
691
692 default:
693 ERR("Invalid location %s.\n", wined3d_debug_location(location));
694 return FALSE;
695 }
696
698 if (buffer->resource.heap_memory && location == WINED3D_LOCATION_BUFFER
699 && !(buffer->resource.usage & WINED3DUSAGE_DYNAMIC))
701
702 return TRUE;
703}
static void wined3d_buffer_evict_sysmem(struct wined3d_buffer *buffer)
Definition: buffer.c:43
static void wined3d_buffer_validate_location(struct wined3d_buffer *buffer, DWORD location)
Definition: buffer.c:101
static void buffer_conversion_upload(struct wined3d_buffer *buffer, struct wined3d_context *context)
Definition: buffer.c:552
#define WINED3D_LOCATION_DISCARDED

Referenced by buffer_conversion_upload(), buffer_unload(), context_load_unordered_access_resources(), create_buffer_texture(), wined3d_buffer_load(), wined3d_buffer_load_location(), wined3d_buffer_load_sysmem(), wined3d_buffer_map(), wined3d_cs_exec_update_sub_resource(), wined3d_rendertarget_view_load_location(), and wined3d_unordered_access_view_clear_uint().

◆ wined3d_buffer_load_sysmem()

BYTE * wined3d_buffer_load_sysmem ( struct wined3d_buffer buffer,
struct wined3d_context context 
)

◆ wined3d_buffer_map()

static HRESULT wined3d_buffer_map ( struct wined3d_buffer buffer,
UINT  offset,
UINT  size,
BYTE **  data,
DWORD  flags 
)
static

Definition at line 1002 of file buffer.c.

1003{
1004 struct wined3d_device *device = buffer->resource.device;
1005 struct wined3d_context *context;
1006 LONG count;
1007 BYTE *base;
1008
1009 TRACE("buffer %p, offset %u, size %u, data %p, flags %#x.\n", buffer, offset, size, data, flags);
1010
1011 count = ++buffer->resource.map_count;
1012
1013 if (buffer->buffer_object)
1014 {
1015 unsigned int dirty_offset = offset, dirty_size = size;
1016
1017 /* DISCARD invalidates the entire buffer, regardless of the specified
1018 * offset and size. Some applications also depend on the entire buffer
1019 * being uploaded in that case. Two such applications are Port Royale
1020 * and Darkstar One. */
1022 {
1023 dirty_offset = 0;
1024 dirty_size = 0;
1025 }
1026
1028 || (!(flags & WINED3D_MAP_WRITE) && (buffer->locations & WINED3D_LOCATION_SYSMEM))
1030 {
1031 if (!(buffer->locations & WINED3D_LOCATION_SYSMEM))
1032 {
1036 }
1037
1040 }
1041 else
1042 {
1043 const struct wined3d_gl_info *gl_info;
1044
1046 gl_info = context->gl_info;
1047
1050 else
1052
1054 buffer_invalidate_bo_range(buffer, dirty_offset, dirty_size);
1055
1056 if ((flags & WINED3D_MAP_DISCARD) && buffer->resource.heap_memory)
1058
1059 if (count == 1)
1060 {
1062
1063 /* Filter redundant WINED3D_MAP_DISCARD maps. The 3DMark2001
1064 * multitexture fill rate test seems to depend on this. When
1065 * we map a buffer with GL_MAP_INVALIDATE_BUFFER_BIT, the
1066 * driver is free to discard the previous contents of the
1067 * buffer. The r600g driver only does this when the buffer is
1068 * currently in use, while the proprietary NVIDIA driver
1069 * appears to do this unconditionally. */
1070 if (buffer->flags & WINED3D_BUFFER_DISCARD)
1071 flags &= ~WINED3D_MAP_DISCARD;
1072
1073 if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
1074 {
1076 buffer->map_ptr = GL_EXTCALL(glMapBufferRange(buffer->buffer_type_hint,
1077 0, buffer->resource.size, mapflags));
1078 checkGLcall("glMapBufferRange");
1079 }
1080 else
1081 {
1082 if (buffer->flags & WINED3D_BUFFER_APPLESYNC)
1083 buffer_sync_apple(buffer, flags, gl_info);
1084 buffer->map_ptr = GL_EXTCALL(glMapBuffer(buffer->buffer_type_hint,
1085 GL_READ_WRITE));
1086 checkGLcall("glMapBuffer");
1087 }
1088
1089 if (((DWORD_PTR)buffer->map_ptr) & (RESOURCE_ALIGNMENT - 1))
1090 {
1091 WARN("Pointer %p is not %u byte aligned.\n", buffer->map_ptr, RESOURCE_ALIGNMENT);
1092
1093 GL_EXTCALL(glUnmapBuffer(buffer->buffer_type_hint));
1094 checkGLcall("glUnmapBuffer");
1095 buffer->map_ptr = NULL;
1096
1097 if (buffer->resource.usage & WINED3DUSAGE_DYNAMIC)
1098 {
1099 /* The extra copy is more expensive than not using VBOs at
1100 * all on the Nvidia Linux driver, which is the only driver
1101 * that returns unaligned pointers.
1102 */
1103 TRACE("Dynamic buffer, dropping VBO.\n");
1105 }
1106 else
1107 {
1108 TRACE("Falling back to doublebuffered operation.\n");
1111 }
1112 TRACE("New pointer is %p.\n", buffer->resource.heap_memory);
1113 }
1114 }
1115
1117 }
1118
1121 }
1122
1123 base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.heap_memory;
1124 *data = base + offset;
1125
1126 TRACE("Returning memory at %p (base %p, offset %u).\n", *data, base, offset);
1127 /* TODO: check Flags compatibility with buffer->currentDesc.Usage (see MSDN) */
1128
1129 return WINED3D_OK;
1130}
static void buffer_sync_apple(struct wined3d_buffer *buffer, DWORD flags, const struct wined3d_gl_info *gl_info)
Definition: buffer.c:815
#define WINED3D_BUFFER_DISCARD
Definition: buffer.c:35
GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags)
Definition: resource.c:515
GLuint GLuint GLsizei count
Definition: gl.h:1545
unsigned int GLbitfield
Definition: gl.h:152
#define GL_READ_WRITE
Definition: glext.h:343
long LONG
Definition: pedump.c:60
#define WINED3D_MAP_WRITE
Definition: wined3d.h:938
#define RESOURCE_ALIGNMENT

Referenced by buffer_resource_sub_resource_map().

◆ wined3d_buffer_prepare_location()

static BOOL wined3d_buffer_prepare_location ( struct wined3d_buffer buffer,
struct wined3d_context context,
DWORD  location 
)
static

Definition at line 608 of file buffer.c.

610{
611 switch (location)
612 {
614 if (buffer->resource.heap_memory)
615 return TRUE;
616
618 {
619 ERR("Failed to allocate system memory.\n");
620 return FALSE;
621 }
622 return TRUE;
623
625 if (buffer->buffer_object)
626 return TRUE;
627
628 if (!(buffer->flags & WINED3D_BUFFER_USE_BO))
629 {
630 WARN("Trying to create BO for buffer %p with no WINED3D_BUFFER_USE_BO.\n", buffer);
631 return FALSE;
632 }
634
635 default:
636 ERR("Invalid location %s.\n", wined3d_debug_location(location));
637 return FALSE;
638 }
639}
static BOOL buffer_create_buffer_object(struct wined3d_buffer *buffer, struct wined3d_context *context)
Definition: buffer.c:197
BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource)
Definition: resource.c:487

Referenced by wined3d_buffer_load(), and wined3d_buffer_load_location().

◆ wined3d_buffer_unmap()

static void wined3d_buffer_unmap ( struct wined3d_buffer buffer)
static

Definition at line 1132 of file buffer.c.

1133{
1134 ULONG i;
1135
1136 TRACE("buffer %p.\n", buffer);
1137
1138 /* In the case that the number of Unmap calls > the
1139 * number of Map calls, d3d returns always D3D_OK.
1140 * This is also needed to prevent Map from returning garbage on
1141 * the next call (this will happen if the lock_count is < 0). */
1142 if (!buffer->resource.map_count)
1143 {
1144 WARN("Unmap called without a previous map call.\n");
1145 return;
1146 }
1147
1148 if (--buffer->resource.map_count)
1149 {
1150 /* Delay loading the buffer until everything is unlocked */
1151 TRACE("Ignoring unmap.\n");
1152 return;
1153 }
1154
1155 if (buffer->map_ptr)
1156 {
1157 struct wined3d_device *device = buffer->resource.device;
1158 const struct wined3d_gl_info *gl_info;
1159 struct wined3d_context *context;
1160
1162 gl_info = context->gl_info;
1163
1165
1166 if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
1167 {
1168 for (i = 0; i < buffer->modified_areas; ++i)
1169 {
1170 GL_EXTCALL(glFlushMappedBufferRange(buffer->buffer_type_hint,
1171 buffer->maps[i].offset, buffer->maps[i].size));
1172 checkGLcall("glFlushMappedBufferRange");
1173 }
1174 }
1175 else if (buffer->flags & WINED3D_BUFFER_APPLESYNC)
1176 {
1177 for (i = 0; i < buffer->modified_areas; ++i)
1178 {
1179 GL_EXTCALL(glFlushMappedBufferRangeAPPLE(buffer->buffer_type_hint,
1180 buffer->maps[i].offset, buffer->maps[i].size));
1181 checkGLcall("glFlushMappedBufferRangeAPPLE");
1182 }
1183 }
1184
1185 GL_EXTCALL(glUnmapBuffer(buffer->buffer_type_hint));
1187 gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
1189
1191 buffer->map_ptr = NULL;
1192 }
1193}
const struct wined3d_gl_info * gl_info

Referenced by buffer_resource_sub_resource_unmap().

◆ wined3d_buffer_upload_data()

void wined3d_buffer_upload_data ( struct wined3d_buffer buffer,
struct wined3d_context context,
const struct wined3d_box box,
const void data 
)

Definition at line 1219 of file buffer.c.

1221{
1222 struct wined3d_map_range range;
1223
1224 if (box)
1225 {
1226 range.offset = box->left;
1227 range.size = box->right - box->left;
1228 }
1229 else
1230 {
1231 range.offset = 0;
1232 range.size = buffer->resource.size;
1233 }
1234
1236}
GLenum GLint * range
Definition: glext.h:7539

Referenced by wined3d_cs_exec_update_sub_resource().

◆ wined3d_buffer_upload_ranges()

static void wined3d_buffer_upload_ranges ( struct wined3d_buffer buffer,
struct wined3d_context context,
const void data,
unsigned int  data_offset,
unsigned int  range_count,
const struct wined3d_map_range ranges 
)
static

Definition at line 535 of file buffer.c.

537{
538 const struct wined3d_gl_info *gl_info = context->gl_info;
539 const struct wined3d_map_range *range;
540
542
543 while (range_count--)
544 {
545 range = &ranges[range_count];
546 GL_EXTCALL(glBufferSubData(buffer->buffer_type_hint,
547 range->offset, range->size, (BYTE *)data + range->offset - data_offset));
548 }
549 checkGLcall("glBufferSubData");
550}

Referenced by buffer_conversion_upload(), wined3d_buffer_load_location(), and wined3d_buffer_upload_data().

◆ wined3d_buffer_validate_location()

static void wined3d_buffer_validate_location ( struct wined3d_buffer buffer,
DWORD  location 
)
static

Definition at line 101 of file buffer.c.

102{
103 TRACE("buffer %p, location %s.\n", buffer, wined3d_debug_location(location));
104
107
108 buffer->locations |= location;
109
110 TRACE("New locations flags are %s.\n", wined3d_debug_location(buffer->locations));
111}
#define location(file, line)
Definition: kmtest.h:18

Referenced by wined3d_buffer_load_location(), and wined3d_buffer_map().

Variable Documentation

◆ buffer_resource_ops

const struct wined3d_resource_ops buffer_resource_ops
static
Initial value:
=
{
}
static void buffer_resource_preload(struct wined3d_resource *resource)
Definition: buffer.c:1248
static ULONG buffer_resource_decref(struct wined3d_resource *resource)
Definition: buffer.c:1243
static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
Definition: buffer.c:1301
static HRESULT buffer_resource_sub_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx, struct wined3d_map_info *info, DWORD flags)
Definition: buffer.c:1283
static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
Definition: buffer.c:1257
static ULONG buffer_resource_incref(struct wined3d_resource *resource)
Definition: buffer.c:1238

Definition at line 1313 of file buffer.c.

Referenced by buffer_init().