#define VB_MAXDECLCHANGES 100 /* After that number we stop converting */
#define VB_RESETDECLCHANGE 1000 /* Reset the changecount after that number of draws */
-/* Context activation is done by the caller. */
static void buffer_create_buffer_object(struct wined3d_buffer *This)
{
GLenum error, gl_usage;
+ IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
TRACE("Creating an OpenGL vertex buffer object for IWineD3DVertexBuffer %p Usage(%s)\n",
This, debug_d3dusage(This->resource.usage));
+ /* Make sure that a context is there. Needed in a multithreaded environment. Otherwise this call is a nop */
+ ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
/* Make sure that the gl error is cleared. Do not use checkGLcall
return ret;
}
-static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct wined3d_stream_info *si,
- UINT attrib_idx, const BOOL check_d3dcolor, const BOOL is_ffp_position, const BOOL is_ffp_color,
- DWORD *stride_this_run, BOOL *float16_used)
+static BOOL buffer_check_attribute(struct wined3d_buffer *This,
+ const struct wined3d_stream_info_element *attrib, const BOOL check_d3dcolor, const BOOL is_ffp_position,
+ const BOOL is_ffp_color, DWORD *stride_this_run, BOOL *float16_used)
{
- const struct wined3d_stream_info_element *attrib = &si->elements[attrib_idx];
BOOL ret = FALSE;
WINED3DFORMAT format;
/* Ignore attributes that do not have our vbo. After that check we can be sure that the attribute is
* there, on nonexistent attribs the vbo is 0.
*/
- if (!(si->use_map & (1 << attrib_idx))
- || attrib->buffer_object != This->buffer_object)
- return FALSE;
+ if (attrib->buffer_object != This->buffer_object) return FALSE;
format = attrib->format_desc->format;
/* Look for newly appeared conversion */
{
WINED3DFORMAT format;
- if (!(strided->use_map & (1 << i)) || strided->elements[i].buffer_object != This->buffer_object) continue;
+ if (strided->elements[i].buffer_object != This->buffer_object) continue;
format = strided->elements[i].format_desc->format;
if (format == WINED3DFMT_R16G16_FLOAT)
static BOOL buffer_find_decl(struct wined3d_buffer *This)
{
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
- const struct wined3d_stream_info *si = &device->strided_streams;
UINT stride_this_run = 0;
BOOL float16_used = FALSE;
BOOL ret = FALSE;
}
for (i = 0; i < MAX_ATTRIBS; ++i)
{
- ret = buffer_check_attribute(This, si, i, FALSE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
+ ret = buffer_check_attribute(This, &device->strided_streams.elements[i],
+ FALSE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
}
/* Recalculate the conversion shift map if the declaration has changed,
if (ret && (float16_used || This->conversion_map))
{
HeapFree(GetProcessHeap(), 0, This->conversion_shift);
- This->conversion_shift = find_conversion_shift(This, si, This->stride);
+ This->conversion_shift = find_conversion_shift(This, &device->strided_streams, This->stride);
}
}
else
* the attributes that our current fixed function pipeline implementation cares for.
*/
BOOL support_d3dcolor = GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA);
- ret = buffer_check_attribute(This, si, WINED3D_FFP_POSITION,
+ ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_POSITION],
TRUE, TRUE, FALSE, &stride_this_run, &float16_used) || ret;
- ret = buffer_check_attribute(This, si, WINED3D_FFP_NORMAL,
+ ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_NORMAL],
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
- ret = buffer_check_attribute(This, si, WINED3D_FFP_DIFFUSE,
+ ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_DIFFUSE],
!support_d3dcolor, FALSE, TRUE, &stride_this_run, &float16_used) || ret;
- ret = buffer_check_attribute(This, si, WINED3D_FFP_SPECULAR,
+ ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_SPECULAR],
!support_d3dcolor, FALSE, TRUE, &stride_this_run, &float16_used) || ret;
- ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD0,
+ ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD0],
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
- ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD1,
+ ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD1],
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
- ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD2,
+ ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD2],
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
- ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD3,
+ ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD3],
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
- ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD4,
+ ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD4],
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
- ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD5,
+ ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD5],
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
- ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD6,
+ ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD6],
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
- ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD7,
+ ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD7],
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
if (float16_used) FIXME("Float16 conversion used with fixed function vertex processing\n");
return ret;
}
-/* Context activation is done by the caller. */
static void buffer_check_buffer_object_size(struct wined3d_buffer *This)
{
UINT size = This->conversion_stride ?
static inline void fixup_transformed_pos(float *p)
{
- /* rhw conversion like in position_float4(). */
- if (p[3] != 1.0f && p[3] != 0.0f)
+ float x, y, z, w;
+
+ /* rhw conversion like in drawStridedSlow */
+ if (p[3] == 1.0 || ((p[3] < eps) && (p[3] > -eps)))
+ {
+ x = p[0];
+ y = p[1];
+ z = p[2];
+ w = 1.0;
+ }
+ else
{
- float w = 1.0f / p[3];
- p[0] *= w;
- p[1] *= w;
- p[2] *= w;
- p[3] = w;
+ w = 1.0 / p[3];
+ x = p[0] * w;
+ y = p[1] * w;
+ z = p[2] * w;
}
+ p[0] = x;
+ p[1] = y;
+ p[2] = z;
+ p[3] = w;
}
-/* Context activation is done by the caller. */
const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object)
{
struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
return refcount;
}
-/* Context activation is done by the caller. */
-BYTE *buffer_get_sysmem(struct wined3d_buffer *This)
+const BYTE *buffer_get_sysmem(struct wined3d_buffer *This)
{
/* AllocatedMemory exists if the buffer is double buffered or has no buffer object at all */
if(This->resource.allocatedMemory) return This->resource.allocatedMemory;
{
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
- ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+ ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
/* Download the buffer, but don't permanently enable double buffering */
if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER))
TRACE("iface %p\n", iface);
- ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
-
if (!This->buffer_object)
{
/* TODO: Make converting independent from VBOs */
if (This->conversion_count > VB_MAXDECLCHANGES)
{
FIXME("Too many declaration changes, stopping converting\n");
-
+ ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
checkGLcall("glDeleteBuffersARB");
if (!device->isInDraw)
{
- ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+ ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
}
ENTER_GL();
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
}
- ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+ ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB));
TRACE("(%p)\n", This);
- /* In the case that the number of Unmap calls > the
- * number of Map calls, d3d returns always D3D_OK.
- * This is also needed to prevent Map from returning garbage on
- * the next call (this will happen if the lock_count is < 0). */
- if(This->lock_count == 0)
- {
- TRACE("Unmap called without a previous Map call!\n");
- return WINED3D_OK;
- }
-
if (InterlockedDecrement(&This->lock_count))
{
/* Delay loading the buffer until everything is unlocked */
IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
}
- ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+ ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint));