wined3d: Merge drawStridedSlow() and drawStridedSlowVs().
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
eeac4013cd
commit
f3c155cc56
|
@ -432,8 +432,9 @@ static inline void fixup_d3dcolor(DWORD *dst_color)
|
|||
{
|
||||
DWORD src_color = *dst_color;
|
||||
|
||||
/* Color conversion like in drawStridedSlow. watch out for little endianity
|
||||
* If we want that stuff to work on big endian machines too we have to consider more things
|
||||
/* Color conversion like in draw_primitive_immediate_mode(). Watch out for
|
||||
* endianness. If we want this to work on big-endian machines as well we
|
||||
* have to consider more things.
|
||||
*
|
||||
* 0xff000000: Alpha mask
|
||||
* 0x00ff0000: Blue mask
|
||||
|
@ -1318,15 +1319,11 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
|
|||
buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER;
|
||||
}
|
||||
|
||||
/* Observations show that draw_primitive_immediate_mode() is faster on
|
||||
* dynamic vertex buffers than converting + drawStridedFast().
|
||||
* (Half-Life 2 and others.) */
|
||||
dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] || gl_info->supported[ARB_MAP_BUFFER_RANGE];
|
||||
|
||||
/* Observations show that drawStridedSlow is faster on dynamic VBs than converting +
|
||||
* drawStridedFast (half-life 2 and others).
|
||||
*
|
||||
* Basically converting the vertices in the buffer is quite expensive, and observations
|
||||
* show that drawStridedSlow is faster than converting + uploading + drawStridedFast.
|
||||
* Therefore do not create a VBO for WINED3DUSAGE_DYNAMIC buffers.
|
||||
*/
|
||||
if (!gl_info->supported[ARB_VERTEX_BUFFER_OBJECT])
|
||||
{
|
||||
TRACE("Not creating a vbo because GL_ARB_vertex_buffer is not supported\n");
|
||||
|
|
|
@ -3101,7 +3101,8 @@ static void context_update_stream_info(struct wined3d_context *context, const st
|
|||
* sources. In most sane cases the pointer - offset will still be > 0,
|
||||
* otherwise it will wrap around to some big value. Hope that with the
|
||||
* indices the driver wraps it back internally. If not,
|
||||
* drawStridedSlow is needed, including a vertex buffer path. */
|
||||
* draw_primitive_immediate_mode() is needed, including a vertex buffer
|
||||
* path. */
|
||||
if (state->load_base_vertex_index < 0)
|
||||
{
|
||||
WARN_(d3d_perf)("load_base_vertex_index is < 0 (%d), not using VBOs.\n",
|
||||
|
@ -3132,7 +3133,7 @@ static void context_update_stream_info(struct wined3d_context *context, const st
|
|||
{
|
||||
if (state->vertex_declaration->half_float_conv_needed && !stream_info->all_vbo)
|
||||
{
|
||||
TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion.\n");
|
||||
TRACE("Using immediate mode draw with vertex shaders for FLOAT16 conversion.\n");
|
||||
context->use_immediate_mode_draw = TRUE;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -5608,9 +5608,9 @@ static void WINE_GLAPI invalid_generic_attrib_func(GLuint idx, const void *data)
|
|||
DebugBreak();
|
||||
}
|
||||
|
||||
/* Helper functions for providing vertex data to opengl. The arrays are initialized based on
|
||||
* the extension detection and are used in drawStridedSlow
|
||||
*/
|
||||
/* Helper functions for providing vertex data to OpenGL. The arrays are
|
||||
* initialised based on the extension detection and are used in
|
||||
* draw_primitive_immediate_mode(). */
|
||||
static void WINE_GLAPI position_d3dcolor(const void *data)
|
||||
{
|
||||
DWORD pos = *((const DWORD *)data);
|
||||
|
|
|
@ -89,80 +89,97 @@ static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primit
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Actually draw using the supplied information.
|
||||
* Slower GL version which extracts info about each vertex in turn
|
||||
*/
|
||||
static unsigned int get_stride_idx(const void *idx_data, unsigned int idx_size,
|
||||
unsigned int base_vertex_idx, unsigned int start_idx, unsigned int vertex_idx)
|
||||
{
|
||||
if (!idx_data)
|
||||
return start_idx + vertex_idx;
|
||||
if (idx_size == 2)
|
||||
return ((const WORD *)idx_data)[start_idx + vertex_idx] + base_vertex_idx;
|
||||
return ((const DWORD *)idx_data)[start_idx + vertex_idx] + base_vertex_idx;
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_context *context,
|
||||
const struct wined3d_stream_info *si, UINT NumVertexes, GLenum glPrimType,
|
||||
const void *idxData, UINT idxSize, UINT startIdx)
|
||||
static void draw_primitive_immediate_mode(struct wined3d_context *context, const struct wined3d_state *state,
|
||||
const struct wined3d_stream_info *si, unsigned int vertex_count, const void *idx_data,
|
||||
unsigned int idx_size, unsigned int start_idx, unsigned int instance_count)
|
||||
{
|
||||
unsigned int textureNo;
|
||||
const WORD *pIdxBufS = NULL;
|
||||
const DWORD *pIdxBufL = NULL;
|
||||
UINT vx_index;
|
||||
const struct wined3d_state *state = &device->state;
|
||||
LONG SkipnStrides = startIdx;
|
||||
BOOL pixelShader = use_ps(state);
|
||||
BOOL specular_fog = FALSE;
|
||||
const BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
|
||||
const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL;
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
const BYTE *position = NULL, *normal = NULL, *diffuse = NULL, *specular = NULL;
|
||||
const struct wined3d_d3d_info *d3d_info = context->d3d_info;
|
||||
const struct wined3d_ffp_attrib_ops *ops = &d3d_info->ffp_attrib_ops;
|
||||
UINT texture_stages = d3d_info->limits.ffp_blend_stages;
|
||||
unsigned int coord_idx, stride_idx, texture_idx, vertex_idx;
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
const struct wined3d_stream_info_element *element;
|
||||
UINT num_untracked_materials;
|
||||
DWORD tex_mask = 0;
|
||||
const BYTE *tex_coords[WINED3DDP_MAXTEXCOORD];
|
||||
unsigned int texture_unit, texture_stages;
|
||||
const struct wined3d_ffp_attrib_ops *ops;
|
||||
unsigned int untracked_material_count;
|
||||
unsigned int tex_mask = 0;
|
||||
BOOL specular_fog = FALSE;
|
||||
BOOL ps = use_ps(state);
|
||||
const void *ptr;
|
||||
|
||||
TRACE_(d3d_perf)("Using slow vertex array code\n");
|
||||
static unsigned int once;
|
||||
|
||||
/* Variable Initialization */
|
||||
if (idxSize)
|
||||
if (!once++)
|
||||
FIXME_(d3d_perf)("Drawing using immediate mode.\n");
|
||||
else
|
||||
WARN_(d3d_perf)("Drawing using immediate mode.\n");
|
||||
|
||||
if (!idx_size && idx_data)
|
||||
ERR("Non-NULL idx_data with 0 idx_size, this should never happen.\n");
|
||||
|
||||
if (instance_count)
|
||||
FIXME("Instancing not implemented.\n");
|
||||
|
||||
/* Immediate mode drawing can't make use of indices in a vbo - get the
|
||||
* data from the index buffer. If the index buffer has no vbo (not
|
||||
* supported or other reason), or with user pointer drawing idx_data
|
||||
* will be non-NULL. */
|
||||
if (idx_size && !idx_data)
|
||||
idx_data = buffer_get_sysmem(state->index_buffer, context);
|
||||
|
||||
ops = &d3d_info->ffp_attrib_ops;
|
||||
|
||||
gl_info->gl_ops.gl.p_glBegin(state->gl_primitive_type);
|
||||
|
||||
if (use_vs(state) || d3d_info->ffp_generic_attributes)
|
||||
{
|
||||
/* Immediate mode drawing can't make use of indices in a vbo - get the
|
||||
* data from the index buffer. If the index buffer has no vbo (not
|
||||
* supported or other reason), or with user pointer drawing idxData
|
||||
* will be non-NULL. */
|
||||
if (!idxData)
|
||||
idxData = buffer_get_sysmem(state->index_buffer, context);
|
||||
for (vertex_idx = 0; vertex_idx < vertex_count; ++vertex_idx)
|
||||
{
|
||||
unsigned int use_map = si->use_map;
|
||||
unsigned int element_idx;
|
||||
|
||||
if (idxSize == 2) pIdxBufS = idxData;
|
||||
else pIdxBufL = idxData;
|
||||
} else if (idxData) {
|
||||
ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
|
||||
stride_idx = get_stride_idx(idx_data, idx_size, state->base_vertex_index, start_idx, vertex_idx);
|
||||
for (element_idx = 0; use_map; use_map >>= 1, ++element_idx)
|
||||
{
|
||||
if (!(use_map & 1u))
|
||||
continue;
|
||||
|
||||
ptr = si->elements[element_idx].data.addr + si->elements[element_idx].stride * stride_idx;
|
||||
ops->generic[si->elements[element_idx].format->emit_idx](element_idx, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
gl_info->gl_ops.gl.p_glEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Start drawing in GL */
|
||||
gl_info->gl_ops.gl.p_glBegin(glPrimType);
|
||||
|
||||
if (si->use_map & (1u << WINED3D_FFP_POSITION))
|
||||
{
|
||||
element = &si->elements[WINED3D_FFP_POSITION];
|
||||
position = element->data.addr;
|
||||
}
|
||||
position = si->elements[WINED3D_FFP_POSITION].data.addr;
|
||||
|
||||
if (si->use_map & (1u << WINED3D_FFP_NORMAL))
|
||||
{
|
||||
element = &si->elements[WINED3D_FFP_NORMAL];
|
||||
normal = element->data.addr;
|
||||
}
|
||||
normal = si->elements[WINED3D_FFP_NORMAL].data.addr;
|
||||
else
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0);
|
||||
}
|
||||
gl_info->gl_ops.gl.p_glNormal3f(0.0f, 0.0f, 0.0f);
|
||||
|
||||
num_untracked_materials = context->num_untracked_materials;
|
||||
untracked_material_count = context->num_untracked_materials;
|
||||
if (si->use_map & (1u << WINED3D_FFP_DIFFUSE))
|
||||
{
|
||||
element = &si->elements[WINED3D_FFP_DIFFUSE];
|
||||
diffuse = element->data.addr;
|
||||
|
||||
if (num_untracked_materials && element->format->id != WINED3DFMT_B8G8R8A8_UNORM)
|
||||
FIXME("Implement diffuse color tracking from %s\n", debug_d3dformat(element->format->id));
|
||||
if (untracked_material_count && element->format->id != WINED3DFMT_B8G8R8A8_UNORM)
|
||||
FIXME("Implement diffuse color tracking from %s.\n", debug_d3dformat(element->format->id));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -174,7 +191,7 @@ static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_
|
|||
element = &si->elements[WINED3D_FFP_SPECULAR];
|
||||
specular = element->data.addr;
|
||||
|
||||
/* special case where the fog density is stored in the specular alpha channel */
|
||||
/* Special case where the fog density is stored in the specular alpha channel. */
|
||||
if (state->render_states[WINED3D_RS_FOGENABLE]
|
||||
&& (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE
|
||||
|| si->elements[WINED3D_FFP_POSITION].format->id == WINED3DFMT_R32G32B32A32_FLOAT)
|
||||
|
@ -182,218 +199,128 @@ static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_
|
|||
{
|
||||
if (gl_info->supported[EXT_FOG_COORD])
|
||||
{
|
||||
if (element->format->id == WINED3DFMT_B8G8R8A8_UNORM) specular_fog = TRUE;
|
||||
else FIXME("Implement fog coordinates from %s\n", debug_d3dformat(element->format->id));
|
||||
if (element->format->id == WINED3DFMT_B8G8R8A8_UNORM)
|
||||
specular_fog = TRUE;
|
||||
else
|
||||
FIXME("Implement fog coordinates from %s.\n", debug_d3dformat(element->format->id));
|
||||
}
|
||||
else
|
||||
{
|
||||
static BOOL warned;
|
||||
static unsigned int once;
|
||||
|
||||
if (!warned)
|
||||
{
|
||||
/* TODO: Use the fog table code from old ddraw */
|
||||
FIXME("Implement fog for transformed vertices in software\n");
|
||||
warned = TRUE;
|
||||
}
|
||||
if (!once++)
|
||||
FIXME("Implement fog for transformed vertices in software.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (gl_info->supported[EXT_SECONDARY_COLOR])
|
||||
{
|
||||
GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
|
||||
GL_EXTCALL(glSecondaryColor3fEXT)(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
for (textureNo = 0; textureNo < texture_stages; ++textureNo)
|
||||
texture_stages = d3d_info->limits.ffp_blend_stages;
|
||||
for (texture_idx = 0; texture_idx < texture_stages; ++texture_idx)
|
||||
{
|
||||
int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
|
||||
DWORD texture_idx = context->tex_unit_map[textureNo];
|
||||
|
||||
if (!gl_info->supported[ARB_MULTITEXTURE] && textureNo > 0)
|
||||
if (!gl_info->supported[ARB_MULTITEXTURE] && texture_idx > 0)
|
||||
{
|
||||
FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
|
||||
FIXME("Program using multiple concurrent textures which this OpenGL implementation doesn't support.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!pixelShader && !state->textures[textureNo]) continue;
|
||||
|
||||
if (texture_idx == WINED3D_UNMAPPED_STAGE) continue;
|
||||
|
||||
if (coordIdx > 7)
|
||||
{
|
||||
TRACE("tex: %d - Skip tex coords, as being system generated\n", textureNo);
|
||||
if (!ps && !state->textures[texture_idx])
|
||||
continue;
|
||||
}
|
||||
else if (coordIdx < 0)
|
||||
|
||||
texture_unit = context->tex_unit_map[texture_idx];
|
||||
if (texture_unit == WINED3D_UNMAPPED_STAGE)
|
||||
continue;
|
||||
|
||||
coord_idx = state->texture_states[texture_idx][WINED3D_TSS_TEXCOORD_INDEX];
|
||||
if (coord_idx > 7)
|
||||
{
|
||||
FIXME("tex: %d - Coord index %d is less than zero, expect a crash.\n", textureNo, coordIdx);
|
||||
TRACE("Skipping generated coordinates (%#x) for texture %u.\n", coord_idx, texture_idx);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coordIdx)))
|
||||
if (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))
|
||||
{
|
||||
element = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
|
||||
texCoords[coordIdx] = element->data.addr;
|
||||
tex_mask |= (1u << textureNo);
|
||||
tex_coords[coord_idx] = si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].data.addr;
|
||||
tex_mask |= (1u << texture_idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo);
|
||||
TRACE("Setting default coordinates for texture %u.\n", texture_idx);
|
||||
if (gl_info->supported[ARB_MULTITEXTURE])
|
||||
GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
|
||||
GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_unit, 0.0f, 0.0f, 0.0f, 1.0f));
|
||||
else
|
||||
gl_info->gl_ops.gl.p_glTexCoord4f(0, 0, 0, 1);
|
||||
gl_info->gl_ops.gl.p_glTexCoord4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/* We shouldn't start this function if any VBO is involved. Should I put a safety check here?
|
||||
* Guess it's not necessary(we crash then anyway) and would only eat CPU time
|
||||
*/
|
||||
/* Blending data and point sizes are not supported by this function. They
|
||||
* are not supported by the fixed function pipeline at all. A FIXME for
|
||||
* them is printed after decoding the vertex declaration. */
|
||||
for (vertex_idx = 0; vertex_idx < vertex_count; ++vertex_idx)
|
||||
{
|
||||
unsigned int tmp_tex_mask;
|
||||
|
||||
/* For each primitive */
|
||||
for (vx_index = 0; vx_index < NumVertexes; ++vx_index) {
|
||||
UINT texture, tmp_tex_mask;
|
||||
/* Blending data and Point sizes are not supported by this function. They are not supported by the fixed
|
||||
* function pipeline at all. A Fixme for them is printed after decoding the vertex declaration
|
||||
*/
|
||||
stride_idx = get_stride_idx(idx_data, idx_size, state->base_vertex_index, start_idx, vertex_idx);
|
||||
|
||||
/* For indexed data, we need to go a few more strides in */
|
||||
if (idxData)
|
||||
if (position)
|
||||
{
|
||||
/* Indexed so work out the number of strides to skip */
|
||||
if (idxSize == 2)
|
||||
SkipnStrides = pIdxBufS[startIdx + vx_index] + state->base_vertex_index;
|
||||
else
|
||||
SkipnStrides = pIdxBufL[startIdx + vx_index] + state->base_vertex_index;
|
||||
ptr = position + stride_idx * si->elements[WINED3D_FFP_POSITION].stride;
|
||||
ops->position[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptr);
|
||||
}
|
||||
|
||||
tmp_tex_mask = tex_mask;
|
||||
for (texture = 0; tmp_tex_mask; tmp_tex_mask >>= 1, ++texture)
|
||||
if (normal)
|
||||
{
|
||||
int coord_idx;
|
||||
const void *ptr;
|
||||
DWORD texture_idx;
|
||||
|
||||
if (!(tmp_tex_mask & 1)) continue;
|
||||
|
||||
coord_idx = state->texture_states[texture][WINED3D_TSS_TEXCOORD_INDEX];
|
||||
ptr = texCoords[coord_idx] + (SkipnStrides * si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].stride);
|
||||
|
||||
texture_idx = context->tex_unit_map[texture];
|
||||
ops->texcoord[si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->emit_idx](
|
||||
GL_TEXTURE0_ARB + texture_idx, ptr);
|
||||
ptr = normal + stride_idx * si->elements[WINED3D_FFP_NORMAL].stride;
|
||||
ops->normal[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptr);
|
||||
}
|
||||
|
||||
/* Diffuse -------------------------------- */
|
||||
if (diffuse)
|
||||
{
|
||||
const void *ptrToCoords = diffuse + SkipnStrides * si->elements[WINED3D_FFP_DIFFUSE].stride;
|
||||
ops->diffuse[si->elements[WINED3D_FFP_DIFFUSE].format->emit_idx](ptrToCoords);
|
||||
ptr = diffuse + stride_idx * si->elements[WINED3D_FFP_DIFFUSE].stride;
|
||||
ops->diffuse[si->elements[WINED3D_FFP_DIFFUSE].format->emit_idx](ptr);
|
||||
|
||||
if (num_untracked_materials)
|
||||
if (untracked_material_count)
|
||||
{
|
||||
struct wined3d_color color;
|
||||
unsigned char i;
|
||||
unsigned int i;
|
||||
|
||||
wined3d_color_from_d3dcolor(&color, *(const DWORD *)ptrToCoords);
|
||||
for (i = 0; i < num_untracked_materials; ++i)
|
||||
wined3d_color_from_d3dcolor(&color, *(const DWORD *)ptr);
|
||||
for (i = 0; i < untracked_material_count; ++i)
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, context->untracked_materials[i], &color.r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Specular ------------------------------- */
|
||||
if (specular)
|
||||
{
|
||||
const void *ptrToCoords = specular + SkipnStrides * si->elements[WINED3D_FFP_SPECULAR].stride;
|
||||
ops->specular[si->elements[WINED3D_FFP_SPECULAR].format->emit_idx](ptrToCoords);
|
||||
ptr = specular + stride_idx * si->elements[WINED3D_FFP_SPECULAR].stride;
|
||||
ops->specular[si->elements[WINED3D_FFP_SPECULAR].format->emit_idx](ptr);
|
||||
|
||||
if (specular_fog)
|
||||
{
|
||||
DWORD specularColor = *(const DWORD *)ptrToCoords;
|
||||
GL_EXTCALL(glFogCoordfEXT((float) (specularColor >> 24)));
|
||||
}
|
||||
GL_EXTCALL(glFogCoordfEXT((float)(*(const DWORD *)ptr >> 24)));
|
||||
}
|
||||
|
||||
/* Normal -------------------------------- */
|
||||
if (normal)
|
||||
tmp_tex_mask = tex_mask;
|
||||
for (texture_idx = 0; tmp_tex_mask; tmp_tex_mask >>= 1, ++texture_idx)
|
||||
{
|
||||
const void *ptrToCoords = normal + SkipnStrides * si->elements[WINED3D_FFP_NORMAL].stride;
|
||||
ops->normal[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptrToCoords);
|
||||
}
|
||||
if (!(tmp_tex_mask & 1))
|
||||
continue;
|
||||
|
||||
/* Position -------------------------------- */
|
||||
if (position)
|
||||
{
|
||||
const void *ptrToCoords = position + SkipnStrides * si->elements[WINED3D_FFP_POSITION].stride;
|
||||
ops->position[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptrToCoords);
|
||||
coord_idx = state->texture_states[texture_idx][WINED3D_TSS_TEXCOORD_INDEX];
|
||||
ptr = tex_coords[coord_idx] + (stride_idx * si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].stride);
|
||||
ops->texcoord[si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->emit_idx](
|
||||
GL_TEXTURE0_ARB + context->tex_unit_map[texture_idx], ptr);
|
||||
}
|
||||
|
||||
/* For non indexed mode, step onto next parts */
|
||||
if (!idxData) ++SkipnStrides;
|
||||
}
|
||||
|
||||
gl_info->gl_ops.gl.p_glEnd();
|
||||
checkGLcall("glEnd and previous calls");
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
static void drawStridedSlowVs(struct wined3d_context *context, const struct wined3d_state *state,
|
||||
const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType,
|
||||
const void *idxData, UINT idxSize, UINT startIdx)
|
||||
{
|
||||
const struct wined3d_ffp_attrib_ops *ops = &context->d3d_info->ffp_attrib_ops;
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
LONG SkipnStrides = startIdx + state->load_base_vertex_index;
|
||||
const DWORD *pIdxBufL = NULL;
|
||||
const WORD *pIdxBufS = NULL;
|
||||
UINT vx_index;
|
||||
int i;
|
||||
const BYTE *ptr;
|
||||
|
||||
if (idxSize)
|
||||
{
|
||||
/* Immediate mode drawing can't make use of indices in a vbo - get the
|
||||
* data from the index buffer. If the index buffer has no vbo (not
|
||||
* supported or other reason), or with user pointer drawing idxData
|
||||
* will be non-NULL. */
|
||||
if (!idxData)
|
||||
idxData = buffer_get_sysmem(state->index_buffer, context);
|
||||
|
||||
if (idxSize == 2) pIdxBufS = idxData;
|
||||
else pIdxBufL = idxData;
|
||||
} else if (idxData) {
|
||||
ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Start drawing in GL */
|
||||
gl_info->gl_ops.gl.p_glBegin(glPrimitiveType);
|
||||
|
||||
for (vx_index = 0; vx_index < numberOfVertices; ++vx_index)
|
||||
{
|
||||
if (idxData)
|
||||
{
|
||||
/* Indexed so work out the number of strides to skip */
|
||||
if (idxSize == 2)
|
||||
SkipnStrides = pIdxBufS[startIdx + vx_index] + state->load_base_vertex_index;
|
||||
else
|
||||
SkipnStrides = pIdxBufL[startIdx + vx_index] + state->load_base_vertex_index;
|
||||
}
|
||||
|
||||
for (i = MAX_ATTRIBS - 1; i >= 0; i--)
|
||||
{
|
||||
if (!(si->use_map & (1u << i))) continue;
|
||||
|
||||
ptr = si->elements[i].data.addr + si->elements[i].stride * SkipnStrides;
|
||||
ops->generic[si->elements[i].format->emit_idx](i, ptr);
|
||||
}
|
||||
SkipnStrides++;
|
||||
}
|
||||
|
||||
gl_info->gl_ops.gl.p_glEnd();
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
static void drawStridedInstanced(struct wined3d_context *context, const struct wined3d_state *state,
|
||||
const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType,
|
||||
|
@ -643,28 +570,8 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co
|
|||
|
||||
if (context->use_immediate_mode_draw || emulation)
|
||||
{
|
||||
/* Immediate mode drawing. */
|
||||
if (use_vs(state))
|
||||
{
|
||||
static BOOL warned;
|
||||
|
||||
if (!warned++)
|
||||
FIXME("Using immediate mode with vertex shaders for half float emulation.\n");
|
||||
else
|
||||
WARN_(d3d_perf)("Using immediate mode with vertex shaders for half float emulation.\n");
|
||||
|
||||
drawStridedSlowVs(context, state, stream_info, index_count,
|
||||
state->gl_primitive_type, idx_data, idx_size, start_idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (context->d3d_info->ffp_generic_attributes)
|
||||
drawStridedSlowVs(context, state, stream_info, index_count,
|
||||
state->gl_primitive_type, idx_data, idx_size, start_idx);
|
||||
else
|
||||
drawStridedSlow(device, context, stream_info, index_count,
|
||||
state->gl_primitive_type, idx_data, idx_size, start_idx);
|
||||
}
|
||||
draw_primitive_immediate_mode(context, state, stream_info, index_count,
|
||||
idx_data, idx_size, start_idx, instance_count);
|
||||
}
|
||||
else if (!gl_info->supported[ARB_INSTANCED_ARRAYS] && instance_count)
|
||||
{
|
||||
|
|
|
@ -1126,10 +1126,10 @@ void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_st
|
|||
/* drop through */
|
||||
|
||||
case WINED3D_FOG_NONE:
|
||||
/* Both are none? According to msdn the alpha channel of the specular
|
||||
* color contains a fog factor. Set it in drawStridedSlow.
|
||||
* Same happens with Vertexfog on transformed vertices
|
||||
*/
|
||||
/* Both are none? According to msdn the alpha channel of
|
||||
* the specular colour contains a fog factor. Set it in
|
||||
* draw_primitive_immediate_mode(). Same happens with
|
||||
* vertex fog on transformed vertices. */
|
||||
new_source = FOGSOURCE_COORD;
|
||||
gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
|
||||
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
|
||||
|
@ -4204,11 +4204,13 @@ static void load_vertex_data(struct wined3d_context *context,
|
|||
warned = TRUE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* TODO: support blends in drawStridedSlow
|
||||
* No need to write a FIXME here, this is done after the general vertex decl decoding
|
||||
*/
|
||||
WARN("unsupported blending in openGl\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: Support vertex blending in immediate mode draws. No need
|
||||
* to write a FIXME here, this is done after the general vertex
|
||||
* declaration decoding. */
|
||||
WARN("Vertex blending not supported.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -4364,18 +4364,20 @@ static void compute_texture_matrix(const struct wined3d_gl_info *gl_info, const
|
|||
/* case WINED3D_TTFF_COUNT1: Won't ever get here. */
|
||||
case WINED3D_TTFF_COUNT2:
|
||||
mat._13 = mat._23 = mat._33 = mat._43 = 0.0f;
|
||||
/* OpenGL divides the first 3 vertex coord by the 4th by default,
|
||||
* which is essentially the same as D3DTTFF_PROJECTED. Make sure that
|
||||
* the 4th coord evaluates to 1.0 to eliminate that.
|
||||
*
|
||||
* If the fixed function pipeline is used, the 4th value remains unused,
|
||||
* so there is no danger in doing this. With vertex shaders we have a
|
||||
* problem. Should an app hit that problem, the code here would have to
|
||||
* check for pixel shaders, and the shader has to undo the default gl divide.
|
||||
*
|
||||
* A more serious problem occurs if the app passes 4 coordinates in, and the
|
||||
* 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
|
||||
* or a replacement shader. */
|
||||
/* OpenGL divides the first 3 vertex coordinates by the 4th by
|
||||
* default, which is essentially the same as D3DTTFF_PROJECTED.
|
||||
* Make sure that the 4th coordinate evaluates to 1.0 to
|
||||
* eliminate that.
|
||||
*
|
||||
* If the fixed function pipeline is used, the 4th value
|
||||
* remains unused, so there is no danger in doing this. With
|
||||
* vertex shaders we have a problem. Should an application hit
|
||||
* that problem, the code here would have to check for pixel
|
||||
* shaders, and the shader has to undo the default GL divide.
|
||||
*
|
||||
* A more serious problem occurs if the application passes 4
|
||||
* coordinates in, and the 4th is != 1.0 (OpenGL default).
|
||||
* This would have to be fixed with immediate mode draws. */
|
||||
default:
|
||||
mat._14 = mat._24 = mat._34 = 0.0f; mat._44 = 1.0f;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue