Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
/*
2
 * Copyright 2011 Joakim Sindholt 
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
7
 * on the rights to use, copy, modify, merge, publish, distribute, sub
8
 * license, and/or sell copies of the Software, and to permit persons to whom
9
 * the Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice (including the next
12
 * paragraph) shall be included in all copies or substantial portions of the
13
 * Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18
 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21
 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
22
 
23
#include "resource9.h"
24
#include "device9.h"
25
#include "nine_helpers.h"
26
#include "nine_defines.h"
27
 
28
#include "pipe/p_screen.h"
29
 
30
#include "util/u_hash_table.h"
31
#include "util/u_inlines.h"
32
 
33
#include "nine_pdata.h"
34
 
35
#define DBG_CHANNEL DBG_RESOURCE
36
 
37
 
38
HRESULT
39
NineResource9_ctor( struct NineResource9 *This,
40
                    struct NineUnknownParams *pParams,
41
                    struct pipe_resource *initResource,
42
                    BOOL Allocate,
43
                    D3DRESOURCETYPE Type,
44
                    D3DPOOL Pool,
45
                    DWORD Usage)
46
{
47
    struct pipe_screen *screen;
48
    HRESULT hr;
49
 
50
    DBG("This=%p pParams=%p initResource=%p Allocate=%d "
51
        "Type=%d Pool=%d Usage=%d\n",
52
        This, pParams, initResource, (int) Allocate,
53
        Type, Pool, Usage);
54
 
55
    hr = NineUnknown_ctor(&This->base, pParams);
56
    if (FAILED(hr))
57
        return hr;
58
 
59
    This->info.screen = screen = This->base.device->screen;
60
    if (initResource)
61
        pipe_resource_reference(&This->resource, initResource);
62
 
63
    if (Allocate) {
64
        assert(!initResource);
65
        DBG("(%p) Creating pipe_resource.\n", This);
66
        This->resource = screen->resource_create(screen, &This->info);
67
        if (!This->resource)
68
            return D3DERR_OUTOFVIDEOMEMORY;
69
    }
70
 
71
    This->type = Type;
72
    This->pool = Pool;
73
    This->usage = Usage;
74
    This->priority = 0;
75
 
76
    This->pdata = util_hash_table_create(ht_guid_hash, ht_guid_compare);
77
    if (!This->pdata)
78
        return E_OUTOFMEMORY;
79
 
80
    return D3D_OK;
81
}
82
 
83
void
84
NineResource9_dtor( struct NineResource9 *This )
85
{
86
    if (This->pdata) {
87
        util_hash_table_foreach(This->pdata, ht_guid_delete, NULL);
88
        util_hash_table_destroy(This->pdata);
89
    }
90
 
91
    /* NOTE: We do have to use refcounting, the driver might
92
     * still hold a reference. */
93
    pipe_resource_reference(&This->resource, NULL);
94
 
95
    NineUnknown_dtor(&This->base);
96
}
97
 
98
struct pipe_resource *
99
NineResource9_GetResource( struct NineResource9 *This )
100
{
101
    return This->resource;
102
}
103
 
104
D3DPOOL
105
NineResource9_GetPool( struct NineResource9 *This )
106
{
107
    return This->pool;
108
}
109
 
110
HRESULT WINAPI
111
NineResource9_SetPrivateData( struct NineResource9 *This,
112
                              REFGUID refguid,
113
                              const void *pData,
114
                              DWORD SizeOfData,
115
                              DWORD Flags )
116
{
117
    enum pipe_error err;
118
    struct pheader *header;
119
    const void *user_data = pData;
120
 
121
    DBG("This=%p refguid=%p pData=%p SizeOfData=%u Flags=%x\n",
122
        This, refguid, pData, SizeOfData, Flags);
123
 
124
    if (Flags & D3DSPD_IUNKNOWN)
125
        user_assert(SizeOfData == sizeof(IUnknown *), D3DERR_INVALIDCALL);
126
 
127
    /* data consists of a header and the actual data. avoiding 2 mallocs */
128
    header = CALLOC_VARIANT_LENGTH_STRUCT(pheader, SizeOfData-1);
129
    if (!header) { return E_OUTOFMEMORY; }
130
    header->unknown = (Flags & D3DSPD_IUNKNOWN) ? TRUE : FALSE;
131
 
132
    /* if the refguid already exists, delete it */
133
    NineResource9_FreePrivateData(This, refguid);
134
 
135
    /* IUnknown special case */
136
    if (header->unknown) {
137
        /* here the pointer doesn't point to the data we want, so point at the
138
         * pointer making what we eventually copy is the pointer itself */
139
        user_data = &pData;
140
    }
141
 
142
    header->size = SizeOfData;
143
    memcpy(header->data, user_data, header->size);
144
 
145
    err = util_hash_table_set(This->pdata, refguid, header);
146
    if (err == PIPE_OK) {
147
        if (header->unknown) { IUnknown_AddRef(*(IUnknown **)header->data); }
148
        return D3D_OK;
149
    }
150
 
151
    FREE(header);
152
    if (err == PIPE_ERROR_OUT_OF_MEMORY) { return E_OUTOFMEMORY; }
153
 
154
    return D3DERR_DRIVERINTERNALERROR;
155
}
156
 
157
HRESULT WINAPI
158
NineResource9_GetPrivateData( struct NineResource9 *This,
159
                              REFGUID refguid,
160
                              void *pData,
161
                              DWORD *pSizeOfData )
162
{
163
    struct pheader *header;
164
 
165
    DBG("This=%p refguid=%p pData=%p pSizeOfData=%p\n",
166
        This, refguid, pData, pSizeOfData);
167
 
168
    user_assert(pSizeOfData, E_POINTER);
169
 
170
    header = util_hash_table_get(This->pdata, refguid);
171
    if (!header) { return D3DERR_NOTFOUND; }
172
 
173
    if (!pData) {
174
        *pSizeOfData = header->size;
175
        return D3D_OK;
176
    }
177
    if (*pSizeOfData < header->size) {
178
        return D3DERR_MOREDATA;
179
    }
180
 
181
    if (header->unknown) { IUnknown_AddRef(*(IUnknown **)header->data); }
182
    memcpy(pData, header->data, header->size);
183
 
184
    return D3D_OK;
185
}
186
 
187
HRESULT WINAPI
188
NineResource9_FreePrivateData( struct NineResource9 *This,
189
                               REFGUID refguid )
190
{
191
    struct pheader *header;
192
 
193
    DBG("This=%p refguid=%p\n", This, refguid);
194
 
195
    header = util_hash_table_get(This->pdata, refguid);
196
    if (!header)
197
        return D3DERR_NOTFOUND;
198
 
199
    ht_guid_delete(NULL, header, NULL);
200
    util_hash_table_remove(This->pdata, refguid);
201
 
202
    return D3D_OK;
203
}
204
 
205
DWORD WINAPI
206
NineResource9_SetPriority( struct NineResource9 *This,
207
                           DWORD PriorityNew )
208
{
209
    DWORD prev = This->priority;
210
 
211
    DBG("This=%p, PriorityNew=%d\n", This, PriorityNew);
212
 
213
    This->priority = PriorityNew;
214
    return prev;
215
}
216
 
217
DWORD WINAPI
218
NineResource9_GetPriority( struct NineResource9 *This )
219
{
220
    return This->priority;
221
}
222
 
223
/* NOTE: Don't forget to adjust locked vtable if you change this ! */
224
void WINAPI
225
NineResource9_PreLoad( struct NineResource9 *This )
226
{
227
    if (This->pool != D3DPOOL_MANAGED)
228
        return;
229
    /* We don't treat managed vertex or index buffers different from
230
     * default ones (are managed vertex buffers even allowed ?), and
231
     * the PreLoad for textures is overridden by superclass.
232
     */
233
}
234
 
235
D3DRESOURCETYPE WINAPI
236
NineResource9_GetType( struct NineResource9 *This )
237
{
238
    return This->type;
239
}