Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/client/graphics/webgl_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1968,6 +1968,22 @@ namespace endor
return -1;
}

vector<int> WebGL2Context::getInternalformatParameter(uint32_t target, uint32_t internalformat, uint32_t pname)
{
// Query the underlying GL implementation via command buffer
auto req = GetInternalformatParameterCommandBufferRequest(target, internalformat, pname);
sendCommandBufferRequest(req, true);
auto response = recvResponse<GetInternalformatParameterCommandBufferResponse>(
COMMAND_BUFFER_GET_INTERNALFORMAT_PARAMETER_RES,
req);

if (response == nullptr) [[unlikely]]
{
throw runtime_error("Failed to get internal format parameter: timeout.");
}
return response->values;
}

int WebGL2Context::getParameterV2(WebGL2IntegerParameterName pname)
{
/**
Expand Down
1 change: 1 addition & 0 deletions src/client/graphics/webgl_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,7 @@ namespace endor
std::optional<int> dstOffset = std::nullopt,
std::optional<int> length = std::nullopt);
int getFragDataLocation(std::shared_ptr<WebGLProgram> program, const std::string &name);
std::vector<int> getInternalformatParameter(uint32_t target, uint32_t internalformat, uint32_t pname);
int getParameterV2(WebGL2IntegerParameterName pname);
std::shared_ptr<WebGLQuery> getQuery(WebGLQueryTarget target, int pname);
int getUniformBlockIndex(std::shared_ptr<WebGLProgram> program, const std::string &uniformBlockName);
Expand Down
51 changes: 51 additions & 0 deletions src/client/script_bindings/webgl/webgl2_rendering_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ namespace endor
// Enhanced framebuffer operations
ADD_WEBGL2_METHOD("blitFramebuffer", BlitFramebuffer)
ADD_WEBGL2_METHOD("renderbufferStorageMultisample", RenderbufferStorageMultisample)
ADD_WEBGL2_METHOD("getInternalformatParameter", GetInternalformatParameter)
ADD_WEBGL2_METHOD("framebufferTextureLayer", FramebufferTextureLayer)

// Enhanced texture operations
Expand Down Expand Up @@ -1703,6 +1704,56 @@ namespace endor
args.GetReturnValue().SetUndefined();
}

void WebGL2RenderingContext::GetInternalformatParameter(const FunctionCallbackInfo<Value> &args)
{
Isolate *isolate = args.GetIsolate();
HandleScope scope(isolate);
Local<Context> context = isolate->GetCurrentContext();

if (args.Length() < 3)
{
isolate->ThrowException(Exception::TypeError(
MakeMethodArgCountError(isolate, "getInternalformatParameter", 3, args.Length())));
return;
}

for (int i = 0; i < 3; ++i)
{
if (!args[i]->IsNumber())
{
isolate->ThrowException(Exception::TypeError(
MakeMethodArgTypeError(isolate, "getInternalformatParameter", i, "number", args[i])));
return;
}
}

uint32_t target = args[0]->Uint32Value(context).ToChecked();
uint32_t internalformat = args[1]->Uint32Value(context).ToChecked();
uint32_t pname = args[2]->Uint32Value(context).ToChecked();

// Delegate to WebGL2Context for the actual query
auto values = handle()->getInternalformatParameter(target, internalformat, pname);

// If empty vector returned, it means unsupported pname - return null per spec
if (values.empty())
{
args.GetReturnValue().SetNull();
return;
}

// Create Int32Array to return the values
auto arraybuffer = ArrayBuffer::New(isolate, sizeof(int32_t) * values.size());
auto backingStore = arraybuffer->GetBackingStore();
int32_t *data = static_cast<int32_t *>(backingStore->Data());
for (size_t i = 0; i < values.size(); i++)
{
data[i] = values[i];
}

Local<Value> result = Int32Array::New(arraybuffer, 0, values.size());
args.GetReturnValue().Set(result);
}

void WebGL2RenderingContext::FramebufferTextureLayer(const v8::FunctionCallbackInfo<v8::Value> &args)
{
Isolate *isolate = args.GetIsolate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ namespace endor
// Enhanced framebuffer operations
void BlitFramebuffer(const v8::FunctionCallbackInfo<v8::Value> &args);
void RenderbufferStorageMultisample(const v8::FunctionCallbackInfo<v8::Value> &args);
void GetInternalformatParameter(const v8::FunctionCallbackInfo<v8::Value> &args);
void FramebufferTextureLayer(const v8::FunctionCallbackInfo<v8::Value> &args);

// Enhanced texture operations
Expand Down
72 changes: 72 additions & 0 deletions src/common/command_buffers/details/properties.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,76 @@ namespace commandbuffers
public:
int error;
};

class GetInternalformatParameterCommandBufferRequest final
: public TrCommandBufferSimpleRequest<GetInternalformatParameterCommandBufferRequest,
COMMAND_BUFFER_GET_INTERNALFORMAT_PARAMETER_REQ>
{
public:
GetInternalformatParameterCommandBufferRequest() = delete;
GetInternalformatParameterCommandBufferRequest(uint32_t target, uint32_t internalformat, uint32_t pname)
: TrCommandBufferSimpleRequest()
, target(target)
, internalformat(internalformat)
, pname(pname)
{
}
GetInternalformatParameterCommandBufferRequest(const GetInternalformatParameterCommandBufferRequest &that,
bool clone = false)
: TrCommandBufferSimpleRequest(that, clone)
, target(that.target)
, internalformat(that.internalformat)
, pname(that.pname)
{
}

public:
uint32_t target;
uint32_t internalformat;
uint32_t pname;
};

class GetInternalformatParameterCommandBufferResponse final
: public TrCommandBufferSimpleResponse<GetInternalformatParameterCommandBufferResponse>
{
public:
GetInternalformatParameterCommandBufferResponse() = delete;
GetInternalformatParameterCommandBufferResponse(GetInternalformatParameterCommandBufferRequest *req,
const std::vector<int> &values)
: TrCommandBufferSimpleResponse(COMMAND_BUFFER_GET_INTERNALFORMAT_PARAMETER_RES, req)
, values(values)
{
}
GetInternalformatParameterCommandBufferResponse(const GetInternalformatParameterCommandBufferResponse &that,
bool clone = false)
: TrCommandBufferSimpleResponse(that, clone)
{
if (clone)
values = that.values;
}

public:
TrCommandBufferMessage *serialize() override
{
auto message = new TrCommandBufferMessage(type, size, this);
if (values.size() > 0)
{
// Serialize the vector using addVecSegment
message->addVecSegment(values);
}
return message;
}

void deserialize(TrCommandBufferMessage &message) override
{
auto valuesSegment = message.nextSegment();
if (valuesSegment != nullptr)
values = valuesSegment->toVec<int>();
else
values.clear();
}

public:
std::vector<int> values;
};
}
4 changes: 3 additions & 1 deletion src/common/command_buffers/macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
XX(SAMPLER_PARAMETERF, SamplerParameterfCommandBufferRequest, "GL::SamplerParameterf") \
XX(GET_SAMPLER_PARAMETER, GetSamplerParameterCommandBufferRequest, "GL::GetSamplerParameter") \
XX(IS_SAMPLER, IsSamplerCommandBufferRequest, "GL::IsSampler") \
XX(GET_INTERNALFORMAT_PARAMETER, GetInternalformatParameterCommandBufferRequest, "GL::GetInternalformatParameter") \
XX(XRFRAME_START, XRFrameStartCommandBufferRequest, "XR::FrameStart") \
XX(XRFRAME_FLUSH, XRFrameFlushCommandBufferRequest, "XR::FrameFlush") \
XX(XRFRAME_END, XRFrameEndCommandBufferRequest, "XR::FrameEnd") \
Expand All @@ -171,4 +172,5 @@
XX(GET_FLOATV, GetFloatvCommandBufferResponse, "GL::GetFloatv") \
XX(GET_STRING, GetStringCommandBufferResponse, "GL::GetString") \
XX(GET_SHADER_PRECISION_FORMAT, GetShaderPrecisionFormatCommandBufferResponse, "GL::GetShaderPrecisionFormat") \
XX(GET_ERROR, GetErrorCommandBufferResponse, "GL::GetError")
XX(GET_ERROR, GetErrorCommandBufferResponse, "GL::GetError") \
XX(GET_INTERNALFORMAT_PARAMETER, GetInternalformatParameterCommandBufferResponse, "GL::GetInternalformatParameter")
2 changes: 2 additions & 0 deletions src/common/command_buffers/shared.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ namespace commandbuffers
COMMAND_BUFFER_GET_SHADER_PRECISION_FORMAT_RES,
COMMAND_BUFFER_GET_ERROR_REQ,
COMMAND_BUFFER_GET_ERROR_RES,
COMMAND_BUFFER_GET_INTERNALFORMAT_PARAMETER_REQ,
COMMAND_BUFFER_GET_INTERNALFORMAT_PARAMETER_RES,

/** XRFrame controls */
COMMAND_BUFFER_XRFRAME_START_REQ,
Expand Down
60 changes: 60 additions & 0 deletions src/renderer/render_api_opengles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2689,6 +2689,63 @@ class RHI_OpenGL : public TrRenderHardwareInterface
DEBUG(DEBUG_TAG, "[%d] GL::GetError() => %d", options.isDefaultQueue(), res.error);
reqContentRenderer->sendCommandBufferResponse(res);
}
TR_OPENGL_FUNC void OnGetInternalformatParameter(GetInternalformatParameterCommandBufferRequest *req,
renderer::TrContentRenderer *reqContentRenderer,
ApiCallOptions &options)
{
std::vector<int> values;

// Support WEBGL_SAMPLES for now, log error for others
if (req->pname == WEBGL_SAMPLES)
{
GLint numSampleCounts = 0;
glGetInternalformativ(req->target, req->internalformat, GL_NUM_SAMPLE_COUNTS, 1, &numSampleCounts);
GLenum error = glGetError();
if (error == GL_NO_ERROR && numSampleCounts > 0)
{
std::vector<GLint> samples(numSampleCounts);
glGetInternalformativ(req->target, req->internalformat, GL_SAMPLES, numSampleCounts, samples.data());
error = glGetError();

if (error == GL_NO_ERROR)
{
for (GLint sample : samples)
{
if (sample > 0)
values.push_back(static_cast<int>(sample));
}
std::sort(values.begin(), values.end(), std::greater<int>());
}
}
if (values.empty())
{
DEBUG(DEBUG_TAG, "[GetInternalformatParameter] Using fallback values {4, 2, 1}");
values = {4, 2, 1};
}
}
else
{
// Not implemented for other pnames
DEBUG(LOG_TAG_ERROR,
"[GetInternalformatParameter] pname 0x%x is not supported.",
req->pname);
}

GetInternalformatParameterCommandBufferResponse res(req, values);
// Note: CheckError is called here but won't detect errors from glGetInternalformativ
// calls above since those errors are already consumed by explicit glGetError() calls
if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall))
{
DEBUG(DEBUG_TAG,
"[%d] GL::GetInternalformativ(0x%x, 0x%x, 0x%x) => [%zu values]",
options.isDefaultQueue(),
req->target,
req->internalformat,
req->pname,
values.size());
}
reqContentRenderer->sendCommandBufferResponse(res);
}
};

void RHI_OpenGL::ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces *interfaces)
Expand Down Expand Up @@ -3026,6 +3083,9 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vector<commandbuffers::TrCommandBufferBase
GetShaderPrecisionFormatCommandBufferRequest,
GetShaderPrecisionFormat)
ADD_COMMAND_BUFFER_HANDLER(GET_ERROR, GetErrorCommandBufferRequest, GetError)
ADD_COMMAND_BUFFER_HANDLER(GET_INTERNALFORMAT_PARAMETER,
GetInternalformatParameterCommandBufferRequest,
GetInternalformatParameter)
#undef ADD_COMMAND_BUFFER_HANDLER
#undef ADD_COMMAND_BUFFER_HANDLER_WITH_DEVICE_FRAME

Expand Down