rsdAllocation.cpp revision eb4fe18dd88634330f9566cbb9e785d8c7ec5813
1eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams/*
2eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * Copyright (C) 2011 The Android Open Source Project
3eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams *
4eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * you may not use this file except in compliance with the License.
6eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * You may obtain a copy of the License at
7eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams *
8eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams *
10eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * Unless required by applicable law or agreed to in writing, software
11eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * See the License for the specific language governing permissions and
14eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * limitations under the License.
15eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams */
16eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
17eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
18eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rsdCore.h"
19eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rsdBcc.h"
20eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rsdRuntime.h"
21eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rsdAllocation.h"
22eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
23eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rsAllocation.h"
24eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
25eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include <GLES/gl.h>
26eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include <GLES2/gl2.h>
27eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include <GLES/glext.h>
28eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
29eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsusing namespace android;
30eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsusing namespace android::renderscript;
31eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
32eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
33eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
34eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsconst static GLenum gFaceOrder[] = {
35eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GL_TEXTURE_CUBE_MAP_POSITIVE_X,
36eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
37eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
38eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
39eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
40eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
41eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams};
42eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
43eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
44eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsstatic void Update2DTexture(const Allocation *alloc, const void *ptr, uint32_t xoff, uint32_t yoff,
45eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                     uint32_t lod, RsAllocationCubemapFace face,
46eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                     uint32_t w, uint32_t h) {
47eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
48eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
49eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const GLenum type = alloc->mHal.state.type->getElement()->getComponent().getGLType();
50eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const GLenum format = alloc->mHal.state.type->getElement()->getComponent().getGLFormat();
51eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsAssert(drv->textureID);
52eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    glBindTexture(drv->glTarget, drv->textureID);
53eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
54eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GLenum t = GL_TEXTURE_2D;
55eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.hasFaces) {
56eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        t = gFaceOrder[face];
57eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
58eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    glTexSubImage2D(t, lod, xoff, yoff, w, h, format, type, ptr);
59eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
60eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
61eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
62eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsstatic void Upload2DTexture(const Context *rsc, const Allocation *alloc, bool isFirstUpload) {
63eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
64eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
65eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GLenum type = alloc->mHal.state.type->getElement()->getComponent().getGLType();
66eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GLenum format = alloc->mHal.state.type->getElement()->getComponent().getGLFormat();
67eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
68eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    glBindTexture(drv->glTarget, drv->textureID);
69eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
70eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
71eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t faceCount = 1;
72eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.hasFaces) {
73eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        faceCount = 6;
74eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
75eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
76eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsdGLCheckError(rsc, "Upload2DTexture 1 ");
77eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    for (uint32_t face = 0; face < faceCount; face ++) {
78eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        for (uint32_t lod = 0; lod < alloc->mHal.state.type->getLODCount(); lod++) {
79eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            const uint8_t *p = (const uint8_t *)drv->mallocPtr;
80eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            p += alloc->mHal.state.type->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0);
81eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
82eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            GLenum t = GL_TEXTURE_2D;
83eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            if (alloc->mHal.state.hasFaces) {
84eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                t = gFaceOrder[face];
85eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            }
86eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
87eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            if (isFirstUpload) {
88eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                glTexImage2D(t, lod, format,
89eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                             alloc->mHal.state.type->getLODDimX(lod),
90eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                             alloc->mHal.state.type->getLODDimY(lod),
91eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                             0, format, type, p);
92eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            } else {
93eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                glTexSubImage2D(t, lod, 0, 0,
94eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                alloc->mHal.state.type->getLODDimX(lod),
95eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                alloc->mHal.state.type->getLODDimY(lod),
96eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                format, type, p);
97eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            }
98eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
99eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
100eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
101eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
102eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        glGenerateMipmap(drv->glTarget);
103eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
104eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsdGLCheckError(rsc, "Upload2DTexture");
105eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
106eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
107eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsstatic void UploadToTexture(const Context *rsc, const Allocation *alloc) {
108eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
109eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
110eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GLenum type = alloc->mHal.state.type->getElement()->getComponent().getGLType();
111eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GLenum format = alloc->mHal.state.type->getElement()->getComponent().getGLFormat();
112eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
113eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!type || !format) {
114eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
115eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
116eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
117eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!alloc->getPtr()) {
118eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
119eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
120eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
121eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    bool isFirstUpload = false;
122eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
123eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv->textureID) {
124eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        glGenTextures(1, &drv->textureID);
125eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        isFirstUpload = true;
126eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
127eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
128eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    Upload2DTexture(rsc, alloc, isFirstUpload);
129eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
130eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
131eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (drv->mallocPtr) {
132eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            free(drv->mallocPtr);
133eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            drv->mallocPtr = NULL;
134eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
135eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
136eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsdGLCheckError(rsc, "UploadToTexture");
137eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
138eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
139eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsstatic void AllocateRenderTarget(const Context *rsc, const Allocation *alloc) {
140eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
141eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
142eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GLenum format = alloc->mHal.state.type->getElement()->getComponent().getGLFormat();
143eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!format) {
144eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
145eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
146eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
147eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv->renderTargetID) {
148eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        glGenRenderbuffers(1, &drv->renderTargetID);
149eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
150eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (!drv->renderTargetID) {
151eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            // This should generally not happen
152eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            LOGE("allocateRenderTarget failed to gen mRenderTargetID");
153eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            rsc->dumpDebug();
154eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            return;
155eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
156eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        glBindRenderbuffer(GL_RENDERBUFFER, drv->renderTargetID);
157eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        glRenderbufferStorage(GL_RENDERBUFFER, format,
158eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                              alloc->mHal.state.dimensionX, alloc->mHal.state.dimensionY);
159eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
160eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsdGLCheckError(rsc, "AllocateRenderTarget");
161eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
162eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
163eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsstatic void UploadToBufferObject(const Context *rsc, const Allocation *alloc) {
164eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
165eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
166eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsAssert(!alloc->mHal.state.type->getDimY());
167eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsAssert(!alloc->mHal.state.type->getDimZ());
168eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
169eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    //alloc->mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
170eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
171eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv->bufferID) {
172eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        glGenBuffers(1, &drv->bufferID);
173eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
174eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv->bufferID) {
175eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        LOGE("Upload to buffer object failed");
176eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->uploadDeferred = true;
177eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
178eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
179eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    glBindBuffer(drv->glTarget, drv->bufferID);
180eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    glBufferData(drv->glTarget, alloc->mHal.state.type->getSizeBytes(),
181eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                 drv->mallocPtr, GL_DYNAMIC_DRAW);
182eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    glBindBuffer(drv->glTarget, 0);
183eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsdGLCheckError(rsc, "UploadToBufferObject");
184eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
185eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
186eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsbool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
187eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
188eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv) {
189eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return false;
190eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
191eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
192eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    void * ptr = malloc(alloc->mHal.state.type->getSizeBytes());
193eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!ptr) {
194eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        free(drv);
195eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return false;
196eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
197eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
198eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->glTarget = GL_NONE;
199eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
200eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (alloc->mHal.state.hasFaces) {
201eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            drv->glTarget = GL_TEXTURE_CUBE_MAP;
202eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        } else {
203eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            drv->glTarget = GL_TEXTURE_2D;
204eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
205eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    } else {
206eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
207eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            drv->glTarget = GL_ARRAY_BUFFER;
208eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
209eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
210eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
211eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    alloc->mHal.drvState.mallocPtr = ptr;
212eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->mallocPtr = (uint8_t *)ptr;
213eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    alloc->mHal.drv = drv;
214eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (forceZero) {
215eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        memset(ptr, 0, alloc->mHal.state.type->getSizeBytes());
216eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
217eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
218eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) {
219eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->uploadDeferred = true;
220eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
221eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    return true;
222eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
223eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
224eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationDestroy(const Context *rsc, Allocation *alloc) {
225eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
226eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
227eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (drv->bufferID) {
228eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        // Causes a SW crash....
229eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        //LOGV(" mBufferID %i", mBufferID);
230eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        //glDeleteBuffers(1, &mBufferID);
231eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        //mBufferID = 0;
232eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
233eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (drv->textureID) {
234eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        glDeleteTextures(1, &drv->textureID);
235eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->textureID = 0;
236eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
237eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (drv->renderTargetID) {
238eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        glDeleteRenderbuffers(1, &drv->renderTargetID);
239eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->renderTargetID = 0;
240eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
241eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
242eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (drv->mallocPtr) {
243eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        free(drv->mallocPtr);
244eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->mallocPtr = NULL;
245eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
246eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    free(drv);
247eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    alloc->mHal.drv = NULL;
248eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
249eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
250eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationResize(const Context *rsc, const Allocation *alloc,
251eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         const Type *newType, bool zeroNew) {
252eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
253eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
254eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->mallocPtr = (uint8_t *)realloc(drv->mallocPtr, newType->getSizeBytes());
255eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
256eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    // fixme
257eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ((Allocation *)alloc)->mHal.drvState.mallocPtr = drv->mallocPtr;
258eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
259eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const uint32_t oldDimX = alloc->mHal.state.dimensionX;
260eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const uint32_t dimX = newType->getDimX();
261eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
262eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (dimX > oldDimX) {
263eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        const Element *e = alloc->mHal.state.type->getElement();
264eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        uint32_t stride = e->getSizeBytes();
265eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        memset(((uint8_t *)drv->mallocPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
266eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
267eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
268eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
269eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
270eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
271eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc,
272eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         RsAllocationUsageType src) {
273eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
274eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
275eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv->uploadDeferred) {
276eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
277eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
278eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
279eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
280eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
281eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
282eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        UploadToTexture(rsc, alloc);
283eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    } else {
284eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
285eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            AllocateRenderTarget(rsc, alloc);
286eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
287eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
288eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
289eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        UploadToBufferObject(rsc, alloc);
290eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
291eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
292eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = false;
293eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
294eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
295eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationMarkDirty(const Context *rsc, const Allocation *alloc) {
296eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
297eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = true;
298eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
299eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
300eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
301eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t xoff, uint32_t lod, uint32_t count,
302eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         const void *data, uint32_t sizeBytes) {
303eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
304eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
305eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const uint32_t eSize = alloc->mHal.state.type->getElementSizeBytes();
306eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint8_t * ptr = drv->mallocPtr;
307eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += eSize * xoff;
308eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t size = count * eSize;
309eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
310eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.hasReferences) {
311eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        alloc->incRefs(data, count);
312eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        alloc->decRefs(ptr, count);
313eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
314eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
315eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memcpy(ptr, data, size);
316eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = true;
317eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
318eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
319eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationData2D(const Context *rsc, const Allocation *alloc,
320eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
321eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
322eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
323eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
324eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t eSize = alloc->mHal.state.elementSizeBytes;
325eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t lineSize = eSize * w;
326eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t destW = alloc->mHal.state.dimensionX;
327eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
328eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (drv->mallocPtr) {
329eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        const uint8_t *src = static_cast<const uint8_t *>(data);
330eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        uint8_t *dst = drv->mallocPtr;
331eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        dst += alloc->mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff);
332eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
333eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        for (uint32_t line=yoff; line < (yoff+h); line++) {
334eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            if (alloc->mHal.state.hasReferences) {
335eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                alloc->incRefs(src, w);
336eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                alloc->decRefs(dst, w);
337eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            }
338eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            memcpy(dst, src, lineSize);
339eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            src += lineSize;
340eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            dst += destW * eSize;
341eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
342eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->uploadDeferred = true;
343eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    } else {
344eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        Update2DTexture(alloc, data, xoff, yoff, lod, face, w, h);
345eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
346eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
347eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
348eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationData3D(const Context *rsc, const Allocation *alloc,
349eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t xoff, uint32_t yoff, uint32_t zoff,
350eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t lod, RsAllocationCubemapFace face,
351eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
352eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
353eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
354eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
355eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationElementData1D(const Context *rsc, const Allocation *alloc,
356eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                uint32_t x,
357eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                const void *data, uint32_t cIdx, uint32_t sizeBytes) {
358eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
359eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
360eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t eSize = alloc->mHal.state.elementSizeBytes;
361eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint8_t * ptr = drv->mallocPtr;
362eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += eSize * x;
363eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
364eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
365eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
366eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
367eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.hasReferences) {
368eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        e->incRefs(data);
369eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        e->decRefs(ptr);
370eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
371eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
372eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memcpy(ptr, data, sizeBytes);
373eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = true;
374eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
375eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
376eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationElementData2D(const Context *rsc, const Allocation *alloc,
377eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                uint32_t x, uint32_t y,
378eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                const void *data, uint32_t cIdx, uint32_t sizeBytes) {
379eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
380eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
381eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t eSize = alloc->mHal.state.elementSizeBytes;
382eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint8_t * ptr = drv->mallocPtr;
383eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += eSize * (x + y * alloc->mHal.state.dimensionX);
384eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
385eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
386eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
387eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
388eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.hasReferences) {
389eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        e->incRefs(data);
390eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        e->decRefs(ptr);
391eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
392eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
393eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memcpy(ptr, data, sizeBytes);
394eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = true;
395eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
396eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
397eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
398