wined3d: Add a separate function for state block initialization.
This commit is contained in:
parent
6a7b97b617
commit
664057ce6a
|
@ -588,273 +588,31 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, WINED3DSTATEBLOCKTYPE Type, IWineD3DStateBlock** ppStateBlock, IUnknown *parent) {
|
static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice *iface,
|
||||||
|
WINED3DSTATEBLOCKTYPE type, IWineD3DStateBlock **stateblock, IUnknown *parent)
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
{
|
||||||
|
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||||
IWineD3DStateBlockImpl *object;
|
IWineD3DStateBlockImpl *object;
|
||||||
unsigned int i, j;
|
HRESULT hr;
|
||||||
HRESULT temp_result;
|
|
||||||
|
|
||||||
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
|
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
|
||||||
if(!object)
|
if(!object)
|
||||||
{
|
{
|
||||||
ERR("Out of memory\n");
|
ERR("Failed to allocate stateblock memory.\n");
|
||||||
*ppStateBlock = NULL;
|
return E_OUTOFMEMORY;
|
||||||
return WINED3DERR_OUTOFVIDEOMEMORY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object->lpVtbl = &IWineD3DStateBlock_Vtbl;
|
hr = stateblock_init(object, This, type, parent);
|
||||||
object->wineD3DDevice = This;
|
if (FAILED(hr))
|
||||||
object->parent = parent;
|
|
||||||
object->ref = 1;
|
|
||||||
object->blockType = Type;
|
|
||||||
|
|
||||||
*ppStateBlock = (IWineD3DStateBlock *)object;
|
|
||||||
|
|
||||||
for(i = 0; i < LIGHTMAP_SIZE; i++) {
|
|
||||||
list_init(&object->lightMap[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
temp_result = allocate_shader_constants(object);
|
|
||||||
if (FAILED(temp_result))
|
|
||||||
{
|
{
|
||||||
|
WARN("Failed to initialize stateblock, hr %#x.\n", hr);
|
||||||
HeapFree(GetProcessHeap(), 0, object);
|
HeapFree(GetProcessHeap(), 0, object);
|
||||||
return temp_result;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special case - Used during initialization to produce a placeholder stateblock
|
TRACE("Created stateblock %p.\n", object);
|
||||||
so other functions called can update a state block */
|
*stateblock = (IWineD3DStateBlock *)object;
|
||||||
if (Type == WINED3DSBT_INIT || Type == WINED3DSBT_RECORDED)
|
|
||||||
{
|
|
||||||
/* Don't bother increasing the reference count otherwise a device will never
|
|
||||||
be freed due to circular dependencies */
|
|
||||||
return WINED3D_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise, might as well set the whole state block to the appropriate values */
|
|
||||||
if (This->stateBlock != NULL)
|
|
||||||
stateblock_copy((IWineD3DStateBlock*) object, (IWineD3DStateBlock*) This->stateBlock);
|
|
||||||
else
|
|
||||||
memset(object->streamFreq, 1, sizeof(object->streamFreq));
|
|
||||||
|
|
||||||
/* Reset the ref and type after kludging it */
|
|
||||||
object->wineD3DDevice = This;
|
|
||||||
object->ref = 1;
|
|
||||||
object->blockType = Type;
|
|
||||||
|
|
||||||
TRACE("Updating changed flags appropriate for type %d\n", Type);
|
|
||||||
|
|
||||||
if (Type == WINED3DSBT_ALL) {
|
|
||||||
|
|
||||||
TRACE("ALL => Pretend everything has changed\n");
|
|
||||||
stateblock_savedstates_set((IWineD3DStateBlock*) object, &object->changed, TRUE);
|
|
||||||
|
|
||||||
/* Lights are not part of the changed / set structure */
|
|
||||||
for(j = 0; j < LIGHTMAP_SIZE; j++) {
|
|
||||||
struct list *e;
|
|
||||||
LIST_FOR_EACH(e, &object->lightMap[j]) {
|
|
||||||
PLIGHTINFOEL *light = LIST_ENTRY(e, PLIGHTINFOEL, entry);
|
|
||||||
light->changed = TRUE;
|
|
||||||
light->enabledChanged = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(j = 1; j <= WINEHIGHEST_RENDER_STATE; j++) {
|
|
||||||
object->contained_render_states[j - 1] = j;
|
|
||||||
}
|
|
||||||
object->num_contained_render_states = WINEHIGHEST_RENDER_STATE;
|
|
||||||
/* TODO: Filter unused transforms between TEXTURE8 and WORLD0? */
|
|
||||||
for(j = 1; j <= HIGHEST_TRANSFORMSTATE; j++) {
|
|
||||||
object->contained_transform_states[j - 1] = j;
|
|
||||||
}
|
|
||||||
object->num_contained_transform_states = HIGHEST_TRANSFORMSTATE;
|
|
||||||
for(j = 0; j < GL_LIMITS(vshader_constantsF); j++) {
|
|
||||||
object->contained_vs_consts_f[j] = j;
|
|
||||||
}
|
|
||||||
object->num_contained_vs_consts_f = GL_LIMITS(vshader_constantsF);
|
|
||||||
for(j = 0; j < MAX_CONST_I; j++) {
|
|
||||||
object->contained_vs_consts_i[j] = j;
|
|
||||||
}
|
|
||||||
object->num_contained_vs_consts_i = MAX_CONST_I;
|
|
||||||
for(j = 0; j < MAX_CONST_B; j++) {
|
|
||||||
object->contained_vs_consts_b[j] = j;
|
|
||||||
}
|
|
||||||
object->num_contained_vs_consts_b = MAX_CONST_B;
|
|
||||||
for(j = 0; j < GL_LIMITS(pshader_constantsF); j++) {
|
|
||||||
object->contained_ps_consts_f[j] = j;
|
|
||||||
}
|
|
||||||
object->num_contained_ps_consts_f = GL_LIMITS(pshader_constantsF);
|
|
||||||
for(j = 0; j < MAX_CONST_I; j++) {
|
|
||||||
object->contained_ps_consts_i[j] = j;
|
|
||||||
}
|
|
||||||
object->num_contained_ps_consts_i = MAX_CONST_I;
|
|
||||||
for(j = 0; j < MAX_CONST_B; j++) {
|
|
||||||
object->contained_ps_consts_b[j] = j;
|
|
||||||
}
|
|
||||||
object->num_contained_ps_consts_b = MAX_CONST_B;
|
|
||||||
for(i = 0; i < MAX_TEXTURES; i++) {
|
|
||||||
for (j = 0; j <= WINED3D_HIGHEST_TEXTURE_STATE; ++j)
|
|
||||||
{
|
|
||||||
object->contained_tss_states[object->num_contained_tss_states].stage = i;
|
|
||||||
object->contained_tss_states[object->num_contained_tss_states].state = j;
|
|
||||||
object->num_contained_tss_states++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(i = 0; i < MAX_COMBINED_SAMPLERS; i++) {
|
|
||||||
for(j = 1; j <= WINED3D_HIGHEST_SAMPLER_STATE; j++) {
|
|
||||||
object->contained_sampler_states[object->num_contained_sampler_states].stage = i;
|
|
||||||
object->contained_sampler_states[object->num_contained_sampler_states].state = j;
|
|
||||||
object->num_contained_sampler_states++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < MAX_STREAMS; i++) {
|
|
||||||
if(object->streamSource[i]) {
|
|
||||||
IWineD3DBuffer_AddRef(object->streamSource[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(object->pIndexData) {
|
|
||||||
IWineD3DBuffer_AddRef(object->pIndexData);
|
|
||||||
}
|
|
||||||
if(object->vertexShader) {
|
|
||||||
IWineD3DVertexShader_AddRef(object->vertexShader);
|
|
||||||
}
|
|
||||||
if(object->pixelShader) {
|
|
||||||
IWineD3DPixelShader_AddRef(object->pixelShader);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (Type == WINED3DSBT_PIXELSTATE) {
|
|
||||||
|
|
||||||
TRACE("PIXELSTATE => Pretend all pixel shates have changed\n");
|
|
||||||
stateblock_savedstates_set((IWineD3DStateBlock*) object, &object->changed, FALSE);
|
|
||||||
|
|
||||||
object->changed.pixelShader = TRUE;
|
|
||||||
|
|
||||||
/* Pixel Shader Constants */
|
|
||||||
for (i = 0; i < GL_LIMITS(pshader_constantsF); ++i) {
|
|
||||||
object->contained_ps_consts_f[i] = i;
|
|
||||||
object->changed.pixelShaderConstantsF[i] = TRUE;
|
|
||||||
}
|
|
||||||
object->num_contained_ps_consts_f = GL_LIMITS(pshader_constantsF);
|
|
||||||
for (i = 0; i < MAX_CONST_B; ++i) {
|
|
||||||
object->contained_ps_consts_b[i] = i;
|
|
||||||
object->changed.pixelShaderConstantsB |= (1 << i);
|
|
||||||
}
|
|
||||||
object->num_contained_ps_consts_b = MAX_CONST_B;
|
|
||||||
for (i = 0; i < MAX_CONST_I; ++i) {
|
|
||||||
object->contained_ps_consts_i[i] = i;
|
|
||||||
object->changed.pixelShaderConstantsI |= (1 << i);
|
|
||||||
}
|
|
||||||
object->num_contained_ps_consts_i = MAX_CONST_I;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) {
|
|
||||||
DWORD rs = SavedPixelStates_R[i];
|
|
||||||
object->changed.renderState[rs >> 5] |= 1 << (rs & 0x1f);
|
|
||||||
object->contained_render_states[i] = rs;
|
|
||||||
}
|
|
||||||
object->num_contained_render_states = NUM_SAVEDPIXELSTATES_R;
|
|
||||||
for (j = 0; j < MAX_TEXTURES; j++) {
|
|
||||||
for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) {
|
|
||||||
DWORD state = SavedPixelStates_T[i];
|
|
||||||
object->changed.textureState[j] |= 1 << state;
|
|
||||||
object->contained_tss_states[object->num_contained_tss_states].stage = j;
|
|
||||||
object->contained_tss_states[object->num_contained_tss_states].state = state;
|
|
||||||
object->num_contained_tss_states++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (j = 0 ; j < MAX_COMBINED_SAMPLERS; j++) {
|
|
||||||
for (i =0; i < NUM_SAVEDPIXELSTATES_S;i++) {
|
|
||||||
DWORD state = SavedPixelStates_S[i];
|
|
||||||
object->changed.samplerState[j] |= 1 << state;
|
|
||||||
object->contained_sampler_states[object->num_contained_sampler_states].stage = j;
|
|
||||||
object->contained_sampler_states[object->num_contained_sampler_states].state = state;
|
|
||||||
object->num_contained_sampler_states++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(object->pixelShader) {
|
|
||||||
IWineD3DPixelShader_AddRef(object->pixelShader);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pixel state blocks do not contain vertex buffers. Set them to NULL to avoid wrong refcounting
|
|
||||||
* on them. This makes releasing the buffer easier
|
|
||||||
*/
|
|
||||||
for(i = 0; i < MAX_STREAMS; i++) {
|
|
||||||
object->streamSource[i] = NULL;
|
|
||||||
}
|
|
||||||
object->pIndexData = NULL;
|
|
||||||
object->vertexShader = NULL;
|
|
||||||
|
|
||||||
} else if (Type == WINED3DSBT_VERTEXSTATE) {
|
|
||||||
|
|
||||||
TRACE("VERTEXSTATE => Pretend all vertex shates have changed\n");
|
|
||||||
stateblock_savedstates_set((IWineD3DStateBlock*) object, &object->changed, FALSE);
|
|
||||||
|
|
||||||
object->changed.vertexShader = TRUE;
|
|
||||||
|
|
||||||
/* Vertex Shader Constants */
|
|
||||||
for (i = 0; i < GL_LIMITS(vshader_constantsF); ++i) {
|
|
||||||
object->changed.vertexShaderConstantsF[i] = TRUE;
|
|
||||||
object->contained_vs_consts_f[i] = i;
|
|
||||||
}
|
|
||||||
object->num_contained_vs_consts_f = GL_LIMITS(vshader_constantsF);
|
|
||||||
for (i = 0; i < MAX_CONST_B; ++i) {
|
|
||||||
object->contained_vs_consts_b[i] = i;
|
|
||||||
object->changed.vertexShaderConstantsB |= (1 << i);
|
|
||||||
}
|
|
||||||
object->num_contained_vs_consts_b = MAX_CONST_B;
|
|
||||||
for (i = 0; i < MAX_CONST_I; ++i) {
|
|
||||||
object->contained_vs_consts_i[i] = i;
|
|
||||||
object->changed.vertexShaderConstantsI |= (1 << i);
|
|
||||||
}
|
|
||||||
object->num_contained_vs_consts_i = MAX_CONST_I;
|
|
||||||
for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
|
|
||||||
DWORD rs = SavedVertexStates_R[i];
|
|
||||||
object->changed.renderState[rs >> 5] |= 1 << (rs & 0x1f);
|
|
||||||
object->contained_render_states[i] = rs;
|
|
||||||
}
|
|
||||||
object->num_contained_render_states = NUM_SAVEDVERTEXSTATES_R;
|
|
||||||
for (j = 0; j < MAX_TEXTURES; j++) {
|
|
||||||
for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) {
|
|
||||||
DWORD state = SavedVertexStates_T[i];
|
|
||||||
object->changed.textureState[j] |= 1 << state;
|
|
||||||
object->contained_tss_states[object->num_contained_tss_states].stage = j;
|
|
||||||
object->contained_tss_states[object->num_contained_tss_states].state = state;
|
|
||||||
object->num_contained_tss_states++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (j = 0 ; j < MAX_COMBINED_SAMPLERS; j++){
|
|
||||||
for (i =0; i < NUM_SAVEDVERTEXSTATES_S;i++) {
|
|
||||||
DWORD state = SavedVertexStates_S[i];
|
|
||||||
object->changed.samplerState[j] |= 1 << state;
|
|
||||||
object->contained_sampler_states[object->num_contained_sampler_states].stage = j;
|
|
||||||
object->contained_sampler_states[object->num_contained_sampler_states].state = state;
|
|
||||||
object->num_contained_sampler_states++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(j = 0; j < LIGHTMAP_SIZE; j++) {
|
|
||||||
struct list *e;
|
|
||||||
LIST_FOR_EACH(e, &object->lightMap[j]) {
|
|
||||||
PLIGHTINFOEL *light = LIST_ENTRY(e, PLIGHTINFOEL, entry);
|
|
||||||
light->changed = TRUE;
|
|
||||||
light->enabledChanged = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < MAX_STREAMS; i++) {
|
|
||||||
if(object->streamSource[i]) {
|
|
||||||
IWineD3DBuffer_AddRef(object->streamSource[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(object->vertexShader) {
|
|
||||||
IWineD3DVertexShader_AddRef(object->vertexShader);
|
|
||||||
}
|
|
||||||
object->pIndexData = NULL;
|
|
||||||
object->pixelShader = NULL;
|
|
||||||
} else {
|
|
||||||
FIXME("Unrecognized state block type %d\n", Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("(%p) returning token (ptr to stateblock) of %p\n", This, object);
|
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||||
/* Allocates the correct amount of space for pixel and vertex shader constants,
|
/* Allocates the correct amount of space for pixel and vertex shader constants,
|
||||||
* along with their set/changed flags on the given stateblock object
|
* along with their set/changed flags on the given stateblock object
|
||||||
*/
|
*/
|
||||||
HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object)
|
static HRESULT stateblock_allocate_shader_constants(IWineD3DStateBlockImpl *object)
|
||||||
{
|
{
|
||||||
IWineD3DStateBlockImpl *This = object;
|
IWineD3DStateBlockImpl *This = object;
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ static inline void stateblock_set_bits(DWORD *map, UINT map_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set all members of a stateblock savedstate to the given value */
|
/** Set all members of a stateblock savedstate to the given value */
|
||||||
void stateblock_savedstates_set(IWineD3DStateBlock *iface, SAVEDSTATES *states, BOOL value)
|
static void stateblock_savedstates_set(IWineD3DStateBlock *iface, SAVEDSTATES *states, BOOL value)
|
||||||
{
|
{
|
||||||
IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
|
IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
|
||||||
unsigned bsize = sizeof(BOOL);
|
unsigned bsize = sizeof(BOOL);
|
||||||
|
@ -167,9 +167,8 @@ void stateblock_savedstates_set(IWineD3DStateBlock *iface, SAVEDSTATES *states,
|
||||||
memset(states->vertexShaderConstantsF, value, bsize * GL_LIMITS(vshader_constantsF));
|
memset(states->vertexShaderConstantsF, value, bsize * GL_LIMITS(vshader_constantsF));
|
||||||
}
|
}
|
||||||
|
|
||||||
void stateblock_copy(
|
static void stateblock_copy(IWineD3DStateBlock *destination, IWineD3DStateBlock *source)
|
||||||
IWineD3DStateBlock* destination,
|
{
|
||||||
IWineD3DStateBlock* source) {
|
|
||||||
int l;
|
int l;
|
||||||
|
|
||||||
IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)source;
|
IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)source;
|
||||||
|
@ -1343,7 +1342,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat
|
||||||
* IWineD3DStateBlock VTbl follows
|
* IWineD3DStateBlock VTbl follows
|
||||||
**********************************************************/
|
**********************************************************/
|
||||||
|
|
||||||
const IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl =
|
static const IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl =
|
||||||
{
|
{
|
||||||
/* IUnknown */
|
/* IUnknown */
|
||||||
IWineD3DStateBlockImpl_QueryInterface,
|
IWineD3DStateBlockImpl_QueryInterface,
|
||||||
|
@ -1356,3 +1355,296 @@ const IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl =
|
||||||
IWineD3DStateBlockImpl_Apply,
|
IWineD3DStateBlockImpl_Apply,
|
||||||
IWineD3DStateBlockImpl_InitStartupStateBlock
|
IWineD3DStateBlockImpl_InitStartupStateBlock
|
||||||
};
|
};
|
||||||
|
|
||||||
|
HRESULT stateblock_init(IWineD3DStateBlockImpl *stateblock, IWineD3DDeviceImpl *device,
|
||||||
|
WINED3DSTATEBLOCKTYPE type, IUnknown *parent)
|
||||||
|
{
|
||||||
|
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
|
||||||
|
unsigned int i, j;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
stateblock->lpVtbl = &IWineD3DStateBlock_Vtbl;
|
||||||
|
stateblock->ref = 1;
|
||||||
|
stateblock->parent = parent;
|
||||||
|
stateblock->wineD3DDevice = device;
|
||||||
|
stateblock->blockType = type;
|
||||||
|
|
||||||
|
for (i = 0; i < LIGHTMAP_SIZE; i++)
|
||||||
|
{
|
||||||
|
list_init(&stateblock->lightMap[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = stateblock_allocate_shader_constants(stateblock);
|
||||||
|
if (FAILED(hr)) return hr;
|
||||||
|
|
||||||
|
/* The WINED3DSBT_INIT stateblock type is used during initialization to
|
||||||
|
* produce a placeholder stateblock so other functions called can update a
|
||||||
|
* state block. */
|
||||||
|
if (type == WINED3DSBT_INIT || type == WINED3DSBT_RECORDED) return WINED3D_OK;
|
||||||
|
|
||||||
|
/* Otherwise, might as well set the whole state block to the appropriate values */
|
||||||
|
if (device->stateBlock) stateblock_copy((IWineD3DStateBlock *)stateblock, (IWineD3DStateBlock *)device->stateBlock);
|
||||||
|
else memset(stateblock->streamFreq, 1, sizeof(stateblock->streamFreq));
|
||||||
|
|
||||||
|
/* Reset the ref and type after kludging it. */
|
||||||
|
stateblock->wineD3DDevice = device;
|
||||||
|
stateblock->ref = 1;
|
||||||
|
stateblock->blockType = type;
|
||||||
|
|
||||||
|
TRACE("Updating changed flags appropriate for type %#x.\n", type);
|
||||||
|
|
||||||
|
if (type == WINED3DSBT_ALL)
|
||||||
|
{
|
||||||
|
TRACE("ALL => Pretend everything has changed.\n");
|
||||||
|
stateblock_savedstates_set((IWineD3DStateBlock *)stateblock, &stateblock->changed, TRUE);
|
||||||
|
|
||||||
|
/* Lights are not part of the changed / set structure. */
|
||||||
|
for (i = 0; i < LIGHTMAP_SIZE; ++i)
|
||||||
|
{
|
||||||
|
struct list *e;
|
||||||
|
LIST_FOR_EACH(e, &stateblock->lightMap[i])
|
||||||
|
{
|
||||||
|
PLIGHTINFOEL *light = LIST_ENTRY(e, PLIGHTINFOEL, entry);
|
||||||
|
light->changed = TRUE;
|
||||||
|
light->enabledChanged = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i <= WINEHIGHEST_RENDER_STATE; ++i)
|
||||||
|
{
|
||||||
|
stateblock->contained_render_states[i - 1] = i;
|
||||||
|
}
|
||||||
|
stateblock->num_contained_render_states = WINEHIGHEST_RENDER_STATE;
|
||||||
|
|
||||||
|
/* TODO: Filter unused transforms between TEXTURE8 and WORLD0? */
|
||||||
|
for (i = 1; i <= HIGHEST_TRANSFORMSTATE; ++i)
|
||||||
|
{
|
||||||
|
stateblock->contained_transform_states[i - 1] = i;
|
||||||
|
}
|
||||||
|
stateblock->num_contained_transform_states = HIGHEST_TRANSFORMSTATE;
|
||||||
|
|
||||||
|
for (i = 0; i < gl_info->max_vshader_constantsF; ++i)
|
||||||
|
{
|
||||||
|
stateblock->contained_vs_consts_f[i] = i;
|
||||||
|
}
|
||||||
|
stateblock->num_contained_vs_consts_f = gl_info->max_vshader_constantsF;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_CONST_I; ++i)
|
||||||
|
{
|
||||||
|
stateblock->contained_vs_consts_i[i] = i;
|
||||||
|
}
|
||||||
|
stateblock->num_contained_vs_consts_i = MAX_CONST_I;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_CONST_B; ++i)
|
||||||
|
{
|
||||||
|
stateblock->contained_vs_consts_b[i] = i;
|
||||||
|
}
|
||||||
|
stateblock->num_contained_vs_consts_b = MAX_CONST_B;
|
||||||
|
|
||||||
|
for (i = 0; i < gl_info->max_pshader_constantsF; ++i)
|
||||||
|
{
|
||||||
|
stateblock->contained_ps_consts_f[i] = i;
|
||||||
|
}
|
||||||
|
stateblock->num_contained_ps_consts_f = gl_info->max_pshader_constantsF;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_CONST_I; ++i)
|
||||||
|
{
|
||||||
|
stateblock->contained_ps_consts_i[i] = i;
|
||||||
|
}
|
||||||
|
stateblock->num_contained_ps_consts_i = MAX_CONST_I;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_CONST_B; ++i)
|
||||||
|
{
|
||||||
|
stateblock->contained_ps_consts_b[i] = i;
|
||||||
|
}
|
||||||
|
stateblock->num_contained_ps_consts_b = MAX_CONST_B;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_TEXTURES; ++i)
|
||||||
|
{
|
||||||
|
for (j = 0; j <= WINED3D_HIGHEST_TEXTURE_STATE; ++j)
|
||||||
|
{
|
||||||
|
stateblock->contained_tss_states[stateblock->num_contained_tss_states].stage = i;
|
||||||
|
stateblock->contained_tss_states[stateblock->num_contained_tss_states].state = j;
|
||||||
|
++stateblock->num_contained_tss_states;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
|
||||||
|
{
|
||||||
|
for (j = 1; j <= WINED3D_HIGHEST_SAMPLER_STATE; ++j)
|
||||||
|
{
|
||||||
|
stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].stage = i;
|
||||||
|
stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].state = j;
|
||||||
|
++stateblock->num_contained_sampler_states;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_STREAMS; ++i)
|
||||||
|
{
|
||||||
|
if (stateblock->streamSource[i]) IWineD3DBuffer_AddRef(stateblock->streamSource[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateblock->pIndexData) IWineD3DBuffer_AddRef(stateblock->pIndexData);
|
||||||
|
if (stateblock->vertexShader) IWineD3DVertexShader_AddRef(stateblock->vertexShader);
|
||||||
|
if (stateblock->pixelShader) IWineD3DPixelShader_AddRef(stateblock->pixelShader);
|
||||||
|
}
|
||||||
|
else if (type == WINED3DSBT_PIXELSTATE)
|
||||||
|
{
|
||||||
|
TRACE("PIXELSTATE => Pretend all pixel states have changed.\n");
|
||||||
|
stateblock_savedstates_set((IWineD3DStateBlock *)stateblock, &stateblock->changed, FALSE);
|
||||||
|
|
||||||
|
/* Pixel Shader Constants. */
|
||||||
|
for (i = 0; i < gl_info->max_pshader_constantsF; ++i)
|
||||||
|
{
|
||||||
|
stateblock->contained_ps_consts_f[i] = i;
|
||||||
|
stateblock->changed.pixelShaderConstantsF[i] = TRUE;
|
||||||
|
}
|
||||||
|
stateblock->num_contained_ps_consts_f = gl_info->max_pshader_constantsF;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_CONST_B; ++i)
|
||||||
|
{
|
||||||
|
stateblock->contained_ps_consts_b[i] = i;
|
||||||
|
stateblock->changed.pixelShaderConstantsB |= (1 << i);
|
||||||
|
}
|
||||||
|
stateblock->num_contained_ps_consts_b = MAX_CONST_B;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_CONST_I; ++i)
|
||||||
|
{
|
||||||
|
stateblock->contained_ps_consts_i[i] = i;
|
||||||
|
stateblock->changed.pixelShaderConstantsI |= (1 << i);
|
||||||
|
}
|
||||||
|
stateblock->num_contained_ps_consts_i = MAX_CONST_I;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++)
|
||||||
|
{
|
||||||
|
DWORD rs = SavedPixelStates_R[i];
|
||||||
|
stateblock->changed.renderState[rs >> 5] |= 1 << (rs & 0x1f);
|
||||||
|
stateblock->contained_render_states[i] = rs;
|
||||||
|
}
|
||||||
|
stateblock->num_contained_render_states = NUM_SAVEDPIXELSTATES_R;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_TEXTURES; ++i)
|
||||||
|
{
|
||||||
|
for (j = 0; j < NUM_SAVEDPIXELSTATES_T; ++j)
|
||||||
|
{
|
||||||
|
DWORD state = SavedPixelStates_T[j];
|
||||||
|
stateblock->changed.textureState[i] |= 1 << state;
|
||||||
|
stateblock->contained_tss_states[stateblock->num_contained_tss_states].stage = i;
|
||||||
|
stateblock->contained_tss_states[stateblock->num_contained_tss_states].state = state;
|
||||||
|
++stateblock->num_contained_tss_states;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0 ; i < MAX_COMBINED_SAMPLERS; ++i)
|
||||||
|
{
|
||||||
|
for (j = 0; j < NUM_SAVEDPIXELSTATES_S; ++j)
|
||||||
|
{
|
||||||
|
DWORD state = SavedPixelStates_S[j];
|
||||||
|
stateblock->changed.samplerState[i] |= 1 << state;
|
||||||
|
stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].stage = i;
|
||||||
|
stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].state = state;
|
||||||
|
stateblock->num_contained_sampler_states++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stateblock->changed.pixelShader = TRUE;
|
||||||
|
if (stateblock->pixelShader) IWineD3DPixelShader_AddRef(stateblock->pixelShader);
|
||||||
|
|
||||||
|
/* Pixel state blocks do not contain vertex buffers. Set them to NULL
|
||||||
|
* to avoid wrong refcounting on them. This makes releasing the buffer
|
||||||
|
* easier. */
|
||||||
|
for (i = 0; i < MAX_STREAMS; ++i)
|
||||||
|
{
|
||||||
|
stateblock->streamSource[i] = NULL;
|
||||||
|
}
|
||||||
|
stateblock->pIndexData = NULL;
|
||||||
|
stateblock->vertexShader = NULL;
|
||||||
|
}
|
||||||
|
else if (type == WINED3DSBT_VERTEXSTATE)
|
||||||
|
{
|
||||||
|
TRACE("VERTEXSTATE => Pretend all vertex shates have changed.\n");
|
||||||
|
stateblock_savedstates_set((IWineD3DStateBlock *)stateblock, &stateblock->changed, FALSE);
|
||||||
|
|
||||||
|
/* Vertex Shader Constants. */
|
||||||
|
for (i = 0; i < gl_info->max_vshader_constantsF; ++i)
|
||||||
|
{
|
||||||
|
stateblock->changed.vertexShaderConstantsF[i] = TRUE;
|
||||||
|
stateblock->contained_vs_consts_f[i] = i;
|
||||||
|
}
|
||||||
|
stateblock->num_contained_vs_consts_f = gl_info->max_vshader_constantsF;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_CONST_B; ++i)
|
||||||
|
{
|
||||||
|
stateblock->contained_vs_consts_b[i] = i;
|
||||||
|
stateblock->changed.vertexShaderConstantsB |= (1 << i);
|
||||||
|
}
|
||||||
|
stateblock->num_contained_vs_consts_b = MAX_CONST_B;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_CONST_I; ++i)
|
||||||
|
{
|
||||||
|
stateblock->contained_vs_consts_i[i] = i;
|
||||||
|
stateblock->changed.vertexShaderConstantsI |= (1 << i);
|
||||||
|
}
|
||||||
|
stateblock->num_contained_vs_consts_i = MAX_CONST_I;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++)
|
||||||
|
{
|
||||||
|
DWORD rs = SavedVertexStates_R[i];
|
||||||
|
stateblock->changed.renderState[rs >> 5] |= 1 << (rs & 0x1f);
|
||||||
|
stateblock->contained_render_states[i] = rs;
|
||||||
|
}
|
||||||
|
stateblock->num_contained_render_states = NUM_SAVEDVERTEXSTATES_R;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_TEXTURES; ++i)
|
||||||
|
{
|
||||||
|
for (j = 0; j < NUM_SAVEDVERTEXSTATES_T; ++j)
|
||||||
|
{
|
||||||
|
DWORD state = SavedVertexStates_T[j];
|
||||||
|
stateblock->changed.textureState[i] |= 1 << state;
|
||||||
|
stateblock->contained_tss_states[stateblock->num_contained_tss_states].stage = i;
|
||||||
|
stateblock->contained_tss_states[stateblock->num_contained_tss_states].state = state;
|
||||||
|
++stateblock->num_contained_tss_states;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0 ; i < MAX_COMBINED_SAMPLERS; ++i)
|
||||||
|
{
|
||||||
|
for (j = 0; j < NUM_SAVEDVERTEXSTATES_S; ++j)
|
||||||
|
{
|
||||||
|
DWORD state = SavedVertexStates_S[j];
|
||||||
|
stateblock->changed.samplerState[i] |= 1 << state;
|
||||||
|
stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].stage = i;
|
||||||
|
stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].state = state;
|
||||||
|
++stateblock->num_contained_sampler_states;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < LIGHTMAP_SIZE; ++i)
|
||||||
|
{
|
||||||
|
struct list *e;
|
||||||
|
LIST_FOR_EACH(e, &stateblock->lightMap[i])
|
||||||
|
{
|
||||||
|
PLIGHTINFOEL *light = LIST_ENTRY(e, PLIGHTINFOEL, entry);
|
||||||
|
light->changed = TRUE;
|
||||||
|
light->enabledChanged = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_STREAMS; ++i)
|
||||||
|
{
|
||||||
|
if (stateblock->streamSource[i]) IWineD3DBuffer_AddRef(stateblock->streamSource[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
stateblock->changed.vertexShader = TRUE;
|
||||||
|
if (stateblock->vertexShader) IWineD3DVertexShader_AddRef(stateblock->vertexShader);
|
||||||
|
|
||||||
|
stateblock->pIndexData = NULL;
|
||||||
|
stateblock->pixelShader = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FIXME("Unrecognized state block type %#x.\n", type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WINED3D_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -2352,10 +2352,8 @@ struct IWineD3DStateBlockImpl
|
||||||
unsigned int num_contained_sampler_states;
|
unsigned int num_contained_sampler_states;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void stateblock_savedstates_set(IWineD3DStateBlock *iface, SAVEDSTATES *states, BOOL value) DECLSPEC_HIDDEN;
|
HRESULT stateblock_init(IWineD3DStateBlockImpl *stateblock, IWineD3DDeviceImpl *device,
|
||||||
extern void stateblock_copy(IWineD3DStateBlock *destination, IWineD3DStateBlock *source) DECLSPEC_HIDDEN;
|
WINED3DSTATEBLOCKTYPE type, IUnknown *parent) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern const IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl DECLSPEC_HIDDEN;
|
|
||||||
|
|
||||||
/* Direct3D terminology with little modifications. We do not have an issued state
|
/* Direct3D terminology with little modifications. We do not have an issued state
|
||||||
* because only the driver knows about it, but we have a created state because d3d
|
* because only the driver knows about it, but we have a created state because d3d
|
||||||
|
|
Loading…
Reference in New Issue